openapi: 3.1.0 info: title: SnapOtter API version: 2.0.0 description: | REST API for SnapOtter, a self-hosted file processing suite with 200+ tools across image, video, audio, document, and data. ## Authentication Most endpoints require authentication via one of two methods: 1. **Session cookie** - Call `POST /api/auth/login` with username and password. The response includes a `token` field. Pass it as `Authorization: Bearer ` on subsequent requests. 2. **API key** - Generate a key via the Settings UI or `POST /api/v1/api-keys`. Keys are prefixed with `si_`. Pass as `Authorization: Bearer si_...`. Endpoints marked with a lock icon require authentication. Admin-only endpoints are noted in their description. license: name: AGPL-3.0 url: https://github.com/snapotter-hq/snapotter/blob/main/LICENSE servers: - url: / description: Current instance tags: - name: Tools description: File processing tools spanning image, video, audio, document, and data. Each accepts a multipart file upload and returns a download URL. - name: Batch description: Process multiple files through a tool in one request. - name: Pipelines description: Chain multiple tools into reusable workflows. - name: Files description: Upload, download, and manage processed files. - name: Auth description: Login, logout, session management, and user administration. - name: API Keys description: Create and manage API keys for programmatic access. - name: Settings description: System-wide configuration (admin only for writes). - name: Teams description: Organize users into teams. - name: Roles description: Custom role management with fine-grained permissions. - name: Audit description: Audit log for tracking administrative actions. - name: Analytics description: Analytics configuration and user consent. - name: Features description: AI feature bundle installation and management. - name: Admin description: Administrative health diagnostics. - name: System description: Health checks, configuration, and job progress. - name: Enterprise description: License-gated enterprise administration, compliance, SCIM, and integration APIs. components: securitySchemes: bearerAuth: type: http scheme: bearer description: Session token from login or API key (prefixed with si_) responses: RateLimited: description: Too many requests. The client has exceeded the rate limit. headers: Retry-After: schema: type: integer description: Seconds until the rate limit window resets X-RateLimit-Limit: schema: type: integer description: Maximum requests per time window X-RateLimit-Remaining: schema: type: integer description: Remaining requests in current window content: application/json: schema: type: object properties: error: type: string example: Rate limit exceeded schemas: Error: type: object required: [error] properties: error: type: string example: Invalid image format details: type: string description: Additional error details (e.g. Zod validation errors) ToolResponse: type: object properties: jobId: type: string description: Unique job identifier downloadUrl: type: string description: URL to download the processed image example: /api/v1/download/abc123/output.png originalSize: type: integer description: Original file size in bytes processedSize: type: integer description: Processed file size in bytes previewUrl: type: string description: URL to a WebP preview (present when output is not browser-previewable, e.g. TIFF, HEIF) savedFileId: type: string description: ID of the auto-saved file in the library (present when fileId was provided in the request) UnauthorizedError: type: object properties: statusCode: type: integer example: 401 error: type: string example: Unauthorized message: type: string example: Authentication required ForbiddenError: type: object properties: statusCode: type: integer example: 403 error: type: string example: Forbidden message: type: string example: Insufficient permissions ConflictError: type: object properties: statusCode: type: integer example: 409 error: type: string example: Conflict message: type: string example: Resource already exists FeatureNotInstalledError: type: object properties: error: type: string example: Feature not installed code: type: string example: FEATURE_NOT_INSTALLED feature: type: string description: Feature bundle identifier featureName: type: string description: Human-readable feature name estimatedSize: type: string description: Estimated download size HealthResponse: type: object properties: status: type: string enum: [healthy, unhealthy] version: type: string AdminHealthResponse: type: object properties: status: type: string enum: [healthy, degraded] version: type: string uptime: type: string storage: type: object properties: mode: type: string available: type: string database: type: string enum: [ok, error] queue: type: object properties: active: type: integer pending: type: integer ai: type: object properties: gpu: type: boolean security: - bearerAuth: [] paths: /api/v1/health: get: operationId: healthCheck tags: [System] summary: Health check description: Returns server health status. Used by Docker HEALTHCHECK. Public endpoint. security: [] responses: "200": description: Server health content: application/json: schema: $ref: "#/components/schemas/HealthResponse" "503": description: Database unavailable content: application/json: schema: $ref: "#/components/schemas/HealthResponse" /api/v1/tools/image/resize: post: operationId: resizeImage tags: [Tools] summary: Resize description: Resize an image to specific dimensions or by percentage. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `width` (number, optional) - Target width in pixels - `height` (number, optional) - Target height in pixels - `fit` (string, default "contain") - One of: contain, cover, fill, inside, outside - `withoutEnlargement` (boolean, default false) - Prevent upscaling - `percentage` (number, optional) - Scale by percentage instead of fixed dimensions responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/content-aware-resize: post: operationId: contentAwareResize tags: [Tools] summary: Content-aware resize description: Resize an image using seam carving to intelligently remove or insert content while preserving important features. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `width` (number, optional) - Target width in pixels - `height` (number, optional) - Target height in pixels - `protectFaces` (boolean, default false) - Detect and protect faces from distortion - `blurRadius` (number 0-20, default 4) - Blur radius for energy map - `sobelThreshold` (number 1-20, default 2) - Edge detection threshold - `square` (boolean, default false) - Crop to square aspect ratio At least one of `width`, `height`, or `square` must be provided. responses: "200": description: Processed image content: application/json: schema: allOf: - $ref: "#/components/schemas/ToolResponse" - type: object properties: width: type: integer height: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/crop: post: operationId: cropImage tags: [Tools] summary: Crop description: Crop an image to a specific region. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `left` (number, required) - Left offset in pixels (min 0) - `top` (number, required) - Top offset in pixels (min 0) - `width` (number, required) - Width of crop region in pixels - `height` (number, required) - Height of crop region in pixels - `unit` (string, optional) - One of: px, percent responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/rotate: post: operationId: rotateImage tags: [Tools] summary: Rotate and flip description: Rotate an image by angle or flip horizontally/vertically. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `angle` (number, default 0) - Rotation angle in degrees - `horizontal` (boolean, default false) - Flip horizontally - `vertical` (boolean, default false) - Flip vertically responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/convert: post: operationId: convertFormat tags: [Tools] summary: Convert format description: Convert an image to a different format. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `format` (string, required) - One of: jpg, png, webp, avif, tiff, gif, heic, heif, jxl, bmp, ico, jp2, qoi, psd - `quality` (number 1-100, optional) - Output quality responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/compress: post: operationId: compressImage tags: [Tools] summary: Compress description: Reduce image file size by quality level or target size. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `mode` (string, default "quality") - One of: quality, targetSize - `quality` (number 1-100, optional) - Compression quality level - `targetSizeKb` (number, optional) - Target file size in kilobytes responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/strip-metadata: post: operationId: stripMetadata tags: [Tools] summary: Strip metadata description: Remove EXIF, GPS, ICC, or XMP metadata from an image. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `stripExif` (boolean, default false) - Remove EXIF data - `stripGps` (boolean, default false) - Remove GPS data - `stripIcc` (boolean, default false) - Remove ICC profile - `stripXmp` (boolean, default false) - Remove XMP data - `stripAll` (boolean, default true) - Remove all metadata responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/border: post: operationId: addBorder tags: [Tools] summary: Border and frame description: Add a border, rounded corners, padding, or shadow to an image. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `borderWidth` (number 0-2000, default 10) - Border thickness in pixels - `borderColor` (hex string, default "#000000") - Border color - `padding` (number 0-200, default 0) - Inner padding in pixels - `paddingColor` (hex string, default "#FFFFFF") - Padding fill color - `cornerRadius` (number 0-2000, default 0) - Corner rounding radius - `shadow` (boolean, default false) - Enable drop shadow - `shadowBlur` (number 1-200, default 15) - Drop shadow blur radius - `shadowOffsetX` (number -50 to 50, default 0) - Shadow horizontal offset - `shadowOffsetY` (number -50 to 50, default 5) - Shadow vertical offset - `shadowColor` (hex string, default "#000000") - Drop shadow color - `shadowOpacity` (number 0-100, default 40) - Shadow opacity percentage responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/beautify: post: operationId: beautifyScreenshot tags: [Tools] summary: Beautify screenshot description: | Add gradient backgrounds, device frames, shadows, watermarks, and social media sizing to screenshots. Supports solid, linear-gradient, radial-gradient, image, and transparent backgrounds. Includes macOS, Windows, browser, iPhone, MacBook, and iPad device frames. Social media presets for Twitter, LinkedIn, Instagram, Facebook, and Product Hunt. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Screenshot or image file to beautify backgroundImage: type: string format: binary description: Optional image for image backgrounds (used when backgroundType is "image") settings: type: string description: | JSON string with options: - `backgroundType` (string, default "linear-gradient") -- One of: solid, linear-gradient, radial-gradient, image, transparent - `backgroundColor` (hex string, default "#667eea") -- Background color (for solid backgrounds) - `gradientStops` (array, default [{color:"#667eea",position:0},{color:"#764ba2",position:100}]) -- Array of {color, position} objects for gradient backgrounds - `gradientAngle` (number 0-360, default 135) -- Gradient angle in degrees - `padding` (number 0-256, default 64) -- Space between screenshot and canvas edge in pixels - `borderRadius` (number 0-64, default 12) -- Corner rounding radius for the screenshot - `shadowPreset` (string, default "subtle") -- One of: none, subtle, medium, dramatic, custom - `shadowBlur` (number 0-100, default 20) -- Shadow blur radius (used with custom shadow preset) - `shadowOffsetX` (number -50 to 50, default 0) -- Shadow horizontal offset - `shadowOffsetY` (number -50 to 50, default 10) -- Shadow vertical offset - `shadowColor` (hex string, default "#000000") -- Shadow color - `shadowOpacity` (number 0-100, default 30) -- Shadow opacity percentage - `frame` (string, default "none") -- One of: none, macos-light, macos-dark, windows-light, windows-dark, browser-light, browser-dark, iphone, iphone-dark, macbook, macbook-dark, ipad, ipad-dark - `frameTitle` (string, optional) -- Title text shown in window title bars - `socialPreset` (string, default "none") -- One of: none, twitter, linkedin, instagram-square, instagram-story, facebook, producthunt - `watermarkText` (string, optional) -- Watermark text to overlay - `watermarkPosition` (string, default "bottom-right") -- One of: top-left, top-right, bottom-left, bottom-right, center - `watermarkOpacity` (number 0-100, default 50) -- Watermark opacity percentage - `outputFormat` (string, default "png") -- One of: png, jpeg, webp responses: "200": description: Beautified image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/adjust-colors: post: operationId: adjustColors tags: [Tools] summary: Color adjustments description: > Consolidated color adjustment tool. Adjusts brightness, contrast, exposure, saturation, temperature, tint, hue, sharpness, color channels, and effects in a single pass. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `brightness` (number -100 to 100, default 0) - Brightness adjustment - `contrast` (number -100 to 100, default 0) - Contrast adjustment - `exposure` (number -100 to 100, default 0) - Exposure adjustment (gamma) - `saturation` (number -100 to 100, default 0) - Color saturation - `temperature` (number -100 to 100, default 0) - Color temperature (cool to warm) - `tint` (number -100 to 100, default 0) - Tint shift (green to magenta) - `hue` (number -180 to 180, default 0) - Hue rotation in degrees - `sharpness` (number 0 to 100, default 0) - Sharpness enhancement - `red` (number 0-200, default 100) - Red channel multiplier - `green` (number 0-200, default 100) - Green channel multiplier - `blue` (number 0-200, default 100) - Blue channel multiplier - `effect` (string, default "none") - One of: none, grayscale, sepia, invert responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/sharpening: post: operationId: sharpenImage tags: [Tools] summary: Sharpening description: Sharpen an image using adaptive, unsharp mask, or high-pass methods with optional noise reduction. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `method` (string, default "adaptive") - One of: adaptive, unsharp-mask, high-pass - `sigma` (number 0.5-10, default 1.0) - Gaussian sigma (adaptive) - `m1` (number 0-10, default 1.0) - Flat area sharpening (adaptive) - `m2` (number 0-20, default 3.0) - Jagged area sharpening (adaptive) - `x1` (number 0-10, default 2.0) - Flat/jagged threshold (adaptive) - `y2` (number 0-50, default 12) - Maximum brightening (adaptive) - `y3` (number 0-50, default 20) - Maximum darkening (adaptive) - `amount` (number 0-1000, default 100) - Sharpen amount (unsharp-mask) - `radius` (number 0.1-5, default 1.0) - Blur radius (unsharp-mask) - `threshold` (number 0-255, default 0) - Luminance threshold (unsharp-mask) - `strength` (number 0-100, default 50) - Blend strength (high-pass) - `kernelSize` (integer, default 3) - One of: 3, 5 (high-pass) - `denoise` (string, default "off") - One of: off, light, medium, strong responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/optimize-for-web: post: operationId: optimizeForWeb tags: [Tools] summary: Optimize for web description: Optimize an image for web delivery by converting to modern formats, adjusting quality, and optionally resizing. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `format` (string, default "webp") - One of: webp, jpeg, avif, png, jxl - `quality` (number 1-100, default 80) - Output quality - `maxWidth` (number, optional) - Maximum width in pixels - `maxHeight` (number, optional) - Maximum height in pixels - `progressive` (boolean, default true) - Enable progressive encoding - `stripMetadata` (boolean, default true) - Remove metadata responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/optimize-for-web/preview: post: operationId: optimizeForWebPreview tags: [Tools] summary: Optimize for web (preview) description: | Lightweight preview endpoint for live parameter tuning. Returns the optimized image binary directly (not JSON). Size information is in response headers. Does not create a workspace or persist results. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to preview settings: type: string description: Same settings as the main optimize-for-web endpoint responses: "200": description: Optimized image binary headers: X-Original-Size: schema: type: string description: Original file size in bytes X-Processed-Size: schema: type: string description: Processed file size in bytes X-Output-Filename: schema: type: string description: Suggested output filename content: image/*: schema: type: string format: binary "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/image-enhancement: post: operationId: enhanceImage tags: [Tools] summary: Image enhancement description: | AI-powered automatic image enhancement. Analyzes the image and applies corrections for exposure, contrast, white balance, saturation, sharpness, and noise based on the selected scene mode. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `mode` (string, default "auto") - One of: auto, portrait, landscape, low-light, food, document - `intensity` (number 0-100, default 50) - Overall enhancement intensity - `corrections` (object, optional) - Toggle individual corrections: - `exposure` (boolean, default true) - `contrast` (boolean, default true) - `whiteBalance` (boolean, default true) - `saturation` (boolean, default true) - `sharpness` (boolean, default true) - `denoise` (boolean, default true) - `deepEnhance` (boolean, default false) - Use AI noise removal for deeper enhancement (requires noise-removal feature) responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/image-enhancement/analyze: post: operationId: analyzeImageEnhancement tags: [Tools] summary: Analyze image for enhancement description: | Analyze an image and return suggested corrections without applying them. Useful for previewing what enhancements would be made. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to analyze responses: "200": description: Image analysis with suggested corrections content: application/json: schema: type: object properties: corrections: type: object description: Suggested correction values metrics: type: object description: Image quality metrics "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "422": description: Analysis failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/noise-removal: post: operationId: removeNoise tags: [Tools] summary: Noise removal description: | AI-powered noise removal using the Python sidecar. Supports multiple quality tiers from quick preview to maximum quality. Requires the noise-removal feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `tier` (string, default "balanced") - One of: quick, balanced, quality, maximum - `strength` (number, default 50) - Denoising strength - `detailPreservation` (number, default 50) - Detail preservation level - `colorNoise` (number, default 30) - Color noise reduction - `format` (string, default "original") - One of: original, png, jpeg, webp, avif, jxl - `quality` (number, default 90) - Output quality (1-100) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/red-eye-removal: post: operationId: removeRedEye tags: [Tools] summary: Red-eye removal description: | AI-powered red-eye detection and removal. Detects faces and corrects red-eye artifacts in photographs. Requires the red-eye-removal feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `sensitivity` (number 0-100, default 50) - Detection sensitivity - `strength` (number 0-100, default 70) - Correction strength - `format` (string, optional) - Output format - `quality` (number 1-100, default 90) - Output quality clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/restore-photo: post: operationId: restorePhoto tags: [Tools] summary: Photo restoration description: | AI-powered photo restoration pipeline. Repairs scratches, enhances faces, denoises, and optionally colorizes old or damaged photographs. Requires the photo-restoration feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `scratchRemoval` (boolean, default true) - Enable scratch repair - `faceEnhancement` (boolean, default true) - Enhance detected faces - `fidelity` (number 0-1, default 0.7) - Face enhancement fidelity - `denoise` (boolean, default true) - Enable denoising - `denoiseStrength` (number 0-100, default 25) - Denoising strength - `colorize` (boolean, default false) - Colorize grayscale photos - `colorizeStrength` (number 0-100, default 85) - Colorization strength clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/passport-photo/analyze: post: operationId: analyzePassportPhoto tags: [Tools] summary: Passport photo - analyze description: | Phase 1 of passport photo generation. Detects face landmarks and removes the background. Returns landmark data and a base64-encoded preview for the client to use in the generate phase. Requires the passport-photo feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Photo with a clear, front-facing face clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Face analysis and background removal result content: application/json: schema: type: object properties: jobId: type: string description: Job ID to pass to the generate endpoint filename: type: string preview: type: string description: Base64-encoded PNG preview of the background-removed image previewWidth: type: integer previewHeight: type: integer landmarks: type: object description: Normalized face landmark coordinates (0-1) properties: leftEye: type: object properties: x: type: number y: type: number rightEye: type: object properties: x: type: number y: type: number eyeCenter: type: object properties: x: type: number y: type: number chin: type: object properties: x: type: number y: type: number forehead: type: object properties: x: type: number y: type: number crown: type: object properties: x: type: number y: type: number nose: type: object properties: x: type: number y: type: number faceCenterX: type: number imageWidth: type: integer imageHeight: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: No face detected or analysis failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/passport-photo/generate: post: operationId: generatePassportPhoto tags: [Tools] summary: Passport photo - generate description: | Phase 2 of passport photo generation. Uses the jobId and landmarks from the analyze phase to crop, resize, and tile the photo to the specified country/document specification. Fast response (no AI re-run). security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [jobId, filename, countryCode, landmarks, imageWidth, imageHeight] properties: jobId: type: string description: Job ID from the analyze phase filename: type: string description: Original filename from analyze phase countryCode: type: string description: ISO country code for passport specification documentType: type: string default: passport description: Document type (passport, visa, etc.) bgColor: type: string default: "#FFFFFF" description: Background color (hex) printLayout: type: string default: none description: Print sheet layout (none, 4x6, A4, letter) maxFileSizeKb: type: number default: 0 description: Max file size in KB (0 = no limit) dpi: type: number minimum: 72 maximum: 1200 default: 300 description: Output DPI customWidthMm: type: number description: Custom photo width in mm (overrides country spec) customHeightMm: type: number description: Custom photo height in mm (overrides country spec) zoom: type: number minimum: 0.5 maximum: 3 default: 1 description: Zoom level (>1 = tighter crop) adjustX: type: number default: 0 description: Horizontal position adjustment adjustY: type: number default: 0 description: Vertical position adjustment landmarks: type: object description: Face landmarks from analyze phase imageWidth: type: integer description: Original image width from analyze phase imageHeight: type: integer description: Original image height from analyze phase responses: "200": description: Generated passport photo content: application/json: schema: type: object properties: jobId: type: string downloadUrl: type: string dimensions: type: object properties: widthMm: type: number heightMm: type: number widthPx: type: integer heightPx: type: integer dpi: type: integer spec: type: object properties: country: type: string countryCode: type: string documentType: type: string documentLabel: type: string printDownloadUrl: type: string description: URL for print sheet download (if printLayout was specified) "400": description: Invalid settings or unknown country code content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Generation failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/colorize: post: operationId: colorizeImage tags: [Tools] summary: Colorize description: | AI-powered photo colorization. Converts black-and-white or grayscale photographs to full color using DDColor with OpenCV DNN fallback. Requires the colorize feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Grayscale or B&W image file settings: type: string description: | JSON string with options: - `intensity` (number 0-1, default 1.0) - Colorization intensity - `model` (string, default "auto") - One of: auto, ddcolor, opencv clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/enhance-faces: post: operationId: enhanceFaces tags: [Tools] summary: Face enhancement description: | AI-powered face enhancement using GFPGAN or CodeFormer. Detects faces in the image and enhances facial details, skin texture, and clarity. Requires the enhance-faces feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file containing faces settings: type: string description: | JSON string with options: - `model` (string, default "auto") - One of: auto, gfpgan, codeformer - `strength` (number 0-1, default 0.8) - Enhancement strength - `onlyCenterFace` (boolean, default false) - Only enhance the center face - `sensitivity` (number 0-1, default 0.5) - Face detection sensitivity clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/image-to-base64: post: operationId: imageToBase64 tags: [Tools] summary: Image to Base64 description: | Convert one or more images to Base64-encoded strings with data URIs. Supports optional format conversion and resizing. Returns both the raw Base64 string and a ready-to-use data URI for each file. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: One or more image files to convert settings: type: string description: | JSON string with options: - `outputFormat` (string, default "original") - One of: original, jpeg, png, webp, avif, jxl - `quality` (integer 1-100, default 80) - Output quality for lossy formats - `maxWidth` (integer, default 0) - Max width in pixels (0 = no limit) - `maxHeight` (integer, default 0) - Max height in pixels (0 = no limit) responses: "200": description: Base64-encoded results content: application/json: schema: type: object properties: results: type: array items: type: object properties: filename: type: string mimeType: type: string width: type: integer height: type: integer originalSize: type: integer description: Original file size in bytes encodedSize: type: integer description: Base64 string size in bytes overheadPercent: type: number description: Size overhead of Base64 encoding base64: type: string description: Raw Base64-encoded image data dataUri: type: string description: Complete data URI (data:mime;base64,...) errors: type: array items: type: object properties: filename: type: string error: type: string "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/watermark-text: post: operationId: addTextWatermark tags: [Tools] summary: Text watermark description: Add a text watermark to an image. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `text` (string 1-500, required) - Watermark text - `fontSize` (number 8-1000, default 48) - Font size in pixels - `color` (hex string, default "#000000") - Text color - `opacity` (number 0-100, default 50) - Opacity percentage - `position` (string, default "center") - One of: center, top-left, top-right, bottom-left, bottom-right, tiled - `rotation` (number -360 to 360, default 0) - Text rotation angle responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/text-overlay: post: operationId: addTextOverlay tags: [Tools] summary: Text overlay description: Add styled text overlay with optional background box. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `text` (string 1-500, required) - Overlay text - `fontSize` (number 8-200, default 48) - Font size in pixels - `color` (hex string, default "#FFFFFF") - Text color - `position` (string, default "bottom") - One of: top, center, bottom - `backgroundBox` (boolean, default false) - Show background box behind text - `backgroundColor` (hex string, default "#000000") - Background box color - `shadow` (boolean, default true) - Add text shadow responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/replace-color: post: operationId: replaceColor tags: [Tools] summary: Replace color description: Replace a specific color in an image with another color or transparency. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `sourceColor` (hex string, default "#FF0000") - Color to replace - `targetColor` (hex string, default "#00FF00") - Replacement color - `makeTransparent` (boolean, default false) - Make matched pixels transparent instead - `tolerance` (number 0-255, default 30) - Color matching tolerance responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/color-blindness: post: operationId: simulateColorBlindness tags: [Tools] summary: Color blindness simulation description: Simulate how an image appears to people with various types of color vision deficiency. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `simulationType` (enum, default "deuteranomaly") -- Type of color vision deficiency to simulate. One of: protanopia, deuteranopia, tritanopia, protanomaly, deuteranomaly, tritanomaly, achromatopsia, blueConeMonochromacy responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/gif-tools: post: operationId: processGif tags: [Tools] summary: GIF tools description: Resize, optimize, speed-adjust, reverse, extract frames from, or rotate animated GIFs. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: GIF file to process settings: type: string description: | JSON string with options: - `mode` (string, default "resize") - One of: resize, optimize, speed, reverse, extract, rotate - `width` (number 1-16384, optional) - Target width in pixels (resize mode) - `height` (number 1-16384, optional) - Target height in pixels (resize mode) - `percentage` (number 1-500, optional) - Scale by percentage (resize mode) - `colors` (number 2-256, default 256) - Color palette size (optimize mode) - `dither` (number 0-1, default 1.0) - Dither amount (optimize mode) - `effort` (number 1-10, default 7) - Compression effort (optimize mode) - `speedFactor` (number 0.1-10, default 1.0) - Speed multiplier (speed mode) - `extractMode` (string, default "single") - One of: single, range, all (extract mode) - `frameNumber` (number, default 0) - Frame index to extract (extract/single mode) - `frameStart` (number, default 0) - Start frame index (extract/range mode) - `frameEnd` (number, optional) - End frame index (extract/range mode) - `extractFormat` (string, default "png") - One of: png, webp (extract mode) - `angle` (number, optional) - Rotation angle, one of: 90, 180, 270 (rotate mode) - `flipH` (boolean, default false) - Flip horizontally (rotate mode) - `flipV` (boolean, default false) - Flip vertically (rotate mode) - `loop` (number 0-100, default 0) - Loop count, 0 = infinite responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/gif-tools/info: post: operationId: getGifInfo tags: [Tools] summary: GIF info description: Get metadata about an animated GIF including dimensions, frame count, delays, and duration. security: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: GIF file to inspect responses: "200": description: GIF metadata content: application/json: schema: type: object properties: width: type: integer height: type: integer pages: type: integer description: Number of frames delay: type: array items: type: integer description: Per-frame delay in milliseconds loop: type: integer description: Loop count (0 = infinite) fileSize: type: integer duration: type: integer description: Total duration in milliseconds "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/smart-crop: post: operationId: smartCrop tags: [Tools] summary: Smart crop description: Smart crop with three modes - subject focus, face focus, or auto trim. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `mode` (string, default "subject") - One of: subject, face, trim, attention (alias for subject), content (alias for trim) - `strategy` (string, default "attention") - One of: attention, entropy (subject mode) - `width` (integer, optional) - Target width in pixels - `height` (integer, optional) - Target height in pixels - `padding` (integer 0-50, default 0) - Padding percentage around focus area - `facePreset` (string, default "head-shoulders") - One of: closeup, head-shoulders, upper-body, half-body (face mode) - `sensitivity` (number 0-1, default 0.5) - Face detection sensitivity (face mode) - `threshold` (integer 0-255, default 30) - Trim tolerance (trim mode) - `padToSquare` (boolean, default false) - Pad to square after trimming (trim mode) - `padColor` (string, default "#ffffff") - Hex color for padding (trim mode) - `targetSize` (integer, optional) - Target size for padded output (trim mode) - `quality` (integer 1-100, optional) - Output quality responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/vectorize: post: operationId: vectorizeImage tags: [Tools] summary: Image to SVG description: Convert a raster image to SVG vector format using potrace (B&W) or VTracer (color). security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `colorMode` (string, default "bw") - One of: bw, color - `threshold` (number 0-255, default 128) - B&W binarization threshold - `colorPrecision` (number 1-16, default 6) - Color bits per channel - `layerDifference` (number 1-128, default 6) - Color gradient step - `filterSpeckle` (number 1-256, default 4) - Noise filter size - `pathMode` (string, default "spline") - One of: none, polygon, spline - `cornerThreshold` (number 0-180, default 60) - Corner detection angle - `invert` (boolean, default false) - Invert colors before tracing responses: "200": description: Processed image (downloadUrl points to .svg file) content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/svg-to-raster: post: operationId: svgToRaster tags: [Tools] summary: SVG to raster description: Convert an SVG file to a raster image format at custom scale and DPI. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: SVG file to convert settings: type: string description: | JSON string with options: - `width` (number 1-65536, optional) - Output width in pixels - `height` (number 1-65536, optional) - Output height in pixels - `dpi` (number 36-2400, default 300) - Render density for SVG rasterization - `quality` (number 1-100, default 90) - Output quality for lossy formats - `backgroundColor` (hex string, default "#00000000") - Background color - `outputFormat` (string, default "png") - One of: png, jpg, webp, avif, tiff, gif, heif, jxl responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/svg-to-raster/batch: post: operationId: svgToRasterBatch tags: [Tools] summary: SVG to raster (batch) description: Convert multiple SVG files to raster images. Returns a ZIP archive. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: SVG files to convert settings: type: string description: Same settings as single-file endpoint clientJobId: type: string description: Optional client-generated job ID for progress tracking responses: "200": description: ZIP archive containing processed images content: application/zip: schema: type: string format: binary "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: All files failed processing content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/image-to-pdf: post: operationId: imageToPdf tags: [Tools] summary: Image to PDF description: Convert one or more images into a PDF document. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: One or more image files to include in the PDF settings: type: string description: | JSON string with options: - `pageSize` (string, default "A4") - One of: A4, Letter, A3, A5 - `orientation` (string, default "portrait") - One of: portrait, landscape - `margin` (number 0-500, default 20) - Page margin in points - `targetSize` (object, optional) - Target output file size - `value` (number, required) - Positive number (decimals allowed) - `unit` (string, required) - One of: KB, MB Minimum effective target is 50KB. When set, images are compressed as JPEG with quality auto-tuned to meet the target. - `collate` (boolean, default true) - When true, all images go into one PDF. When false, each image becomes a separate PDF and the result is a ZIP. responses: "200": description: Generated PDF (downloadUrl points to .pdf file) content: application/json: schema: allOf: - $ref: "#/components/schemas/ToolResponse" - type: object properties: pages: type: integer description: Number of images/pages in the PDF compression: type: object description: Present only when targetSize was specified properties: targetRequested: type: integer description: Target size in bytes targetMet: type: boolean description: Whether the target was achieved jpegQuality: type: integer description: Final JPEG quality used (10-95) "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/pdf/pdf-to-image: post: operationId: pdfToImage tags: [Tools] summary: PDF to image description: Convert PDF pages to images. Returns individual page downloads and a ZIP of all pages. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to convert settings: type: string description: | JSON string with options: - `format` (string, default "png") - Output format: png, jpg, webp, avif, tiff, gif, heic, heif, jxl - `dpi` (number 36-2400, default 150) - Resolution in dots per inch - `quality` (number 1-100, default 85) - Output quality - `colorMode` (string, default "color") - One of: color, grayscale, bw - `pages` (string, default "all") - Page selection, e.g. "all", "1-3", "1,3,5" responses: "200": description: Converted pages content: application/json: schema: type: object properties: jobId: type: string pageCount: type: integer description: Total pages in the PDF selectedPages: type: array items: type: integer format: type: string pages: type: array items: type: object properties: page: type: integer downloadUrl: type: string size: type: integer zipUrl: type: string description: URL to download all pages as ZIP zipSize: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/pdf-to-image/info: post: operationId: getPdfInfo tags: [Tools] summary: PDF page count description: Get the number of pages in a PDF file. security: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to inspect responses: "200": description: PDF info content: application/json: schema: type: object properties: pageCount: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/pdf/pdf-to-image/preview: post: operationId: previewPdfPages tags: [Tools] summary: PDF page thumbnails description: Generate thumbnail previews for each page in a PDF (max 200 pages, JPEG 300px wide). security: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to preview responses: "200": description: Page thumbnails content: application/json: schema: type: object properties: pageCount: type: integer thumbnails: type: array items: type: object properties: page: type: integer dataUrl: type: string description: Base64-encoded JPEG data URL width: type: integer height: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/split: post: operationId: splitImage tags: [Tools] summary: Split image description: Split an image into a grid of tiles. Returns a ZIP file. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to split settings: type: string description: | JSON string with options: - `columns` (number 1-100, default 3) - Number of columns - `rows` (number 1-100, default 3) - Number of rows - `tileWidth` (number, min 10, optional) - Fixed tile width in pixels - `tileHeight` (number, min 10, optional) - Fixed tile height in pixels - `outputFormat` (string, default "original") - One of: original, png, jpg, webp, avif, jxl - `quality` (number 1-100, default 90) - Output quality responses: "200": description: ZIP archive with results content: application/zip: schema: type: string format: binary "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/bulk-rename: post: operationId: bulkRename tags: [Tools] summary: Bulk rename description: Rename multiple images using a pattern template. Supports {{index}}, {{padded}}, and {{original}} tokens. Returns a ZIP file. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Multiple image files to rename settings: type: string description: | JSON string with options: - `pattern` (string 1-1000, default "image-{{index}}") - Naming pattern template - `startIndex` (number, default 1) - Starting index number responses: "200": description: ZIP archive with results content: application/zip: schema: type: string format: binary "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/favicon: post: operationId: generateFavicon tags: [Tools] summary: Favicon generator description: Generate a complete favicon set (16px to 512px PNGs, ICO, and manifest.json) from an image. Returns a ZIP file. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to use as favicon source responses: "200": description: ZIP archive with results content: application/zip: schema: type: string format: binary "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/watermark-image: post: operationId: addImageWatermark tags: [Tools] summary: Image watermark description: Add an image watermark overlay. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file, watermark] properties: file: type: string format: binary description: Main image file watermark: type: string format: binary description: Watermark overlay image settings: type: string description: | JSON string with options: - `position` (string, default "bottom-right") - One of: center, top-left, top-right, bottom-left, bottom-right - `opacity` (number 0-100, default 50) - Watermark opacity percentage - `scale` (number 1-100, default 25) - Watermark size as percentage of base image responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/compose: post: operationId: composeImages tags: [Tools] summary: Image composition description: Composite an overlay image onto a base image with blend modes. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file, overlay] properties: file: type: string format: binary description: Base image file overlay: type: string format: binary description: Overlay image file settings: type: string description: | JSON string with options: - `x` (number, default 0) - Horizontal offset of overlay - `y` (number, default 0) - Vertical offset of overlay - `opacity` (number 0-100, default 100) - Overlay opacity percentage - `blendMode` (string, default "over") - One of: over, multiply, screen, overlay, darken, lighten, hard-light, soft-light, difference, exclusion responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/meme-generator: post: operationId: generateMeme tags: [Tools] summary: Meme generator description: > Create memes using templates or custom images. Supports two modes: (1) Template mode - send JSON body with `templateId` and `textBoxes`. (2) Custom image mode - send multipart with `file` and `settings`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: Custom image file (optional if using templateId) settings: type: string description: | JSON string with options: - `templateId` (string, optional) - ID of a meme template from /api/v1/meme-templates - `textLayout` (string, default "top-bottom") - One of: top-bottom, top-only, bottom-only, center, side-by-side - `textBoxes` (array of {id, text}) - Text content for each position - `fontFamily` (string, default "anton") - One of: anton, arial-black, comic-sans, montserrat, bebas-neue, permanent-marker, roboto - `fontSize` (number 8-200, optional) - Font size in pixels - `textColor` (hex string, default "#ffffff") - Text color - `strokeColor` (hex string, default "#000000") - Text outline color - `textAlign` (string, default "center") - One of: left, center, right - `allCaps` (boolean, default true) - Convert text to uppercase application/json: schema: type: object description: Template mode - send templateId and textBoxes as JSON body properties: templateId: type: string description: ID of a meme template textBoxes: type: array items: type: object properties: id: type: string text: type: string responses: "200": description: Processed meme image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or template not found content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/meme-templates: get: operationId: listMemeTemplates tags: [Tools] summary: List meme templates description: Returns the full manifest of available meme templates including text box positions. security: - bearerAuth: [] responses: "200": description: Meme template manifest content: application/json: schema: type: object properties: templates: type: array items: type: object properties: id: type: string filename: type: string width: type: integer height: type: integer textBoxes: type: array items: type: object properties: id: type: string x: type: number y: type: number width: type: number height: type: number defaultText: type: string "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/meme-templates/full/{filename}: get: operationId: getMemeTemplateImage tags: [Tools] summary: Get meme template image description: Serve a full-size meme template image. security: - bearerAuth: [] parameters: - name: filename in: path required: true schema: type: string description: Template image filename responses: "200": description: Template image content: image/*: schema: type: string format: binary "400": description: Invalid filename content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Template not found content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/meme-templates/thumbs/{filename}: get: operationId: getMemeTemplateThumbnail tags: [Tools] summary: Get meme template thumbnail description: Serve a thumbnail of a meme template. security: - bearerAuth: [] parameters: - name: filename in: path required: true schema: type: string description: Template thumbnail filename responses: "200": description: Thumbnail image content: image/*: schema: type: string format: binary "400": description: Invalid filename content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Thumbnail not found content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/meme-templates/fonts/{filename}: get: operationId: getMemeTemplateFont tags: [Tools] summary: Get meme template font description: Serve a font file used by the meme generator. security: - bearerAuth: [] parameters: - name: filename in: path required: true schema: type: string description: Font filename (e.g. anton.ttf) responses: "200": description: Font file content: font/ttf: schema: type: string format: binary "400": description: Invalid filename content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Font not found content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/compare: post: operationId: compareImages tags: [Tools] summary: Image compare description: Compare two images and generate a visual difference report. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file1, file2] properties: file1: type: string format: binary description: First image to compare file2: type: string format: binary description: Second image to compare responses: "200": description: Comparison result content: application/json: schema: allOf: - $ref: "#/components/schemas/ToolResponse" - type: object properties: similarity: type: number description: Similarity percentage (0-100) dimensions: type: object properties: width: type: integer height: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/erase-object: post: operationId: eraseObject tags: [Tools] summary: Object eraser description: Erase objects from an image using a mask. White areas in the mask indicate regions to erase. Uses LaMa inpainting. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [image, mask] properties: image: type: string format: binary description: Source image file mask: type: string format: binary description: Mask image (white areas will be erased) format: type: string enum: [auto, png, jpg, jpeg, webp, tiff, gif, avif, heic, heif, jxl] default: auto description: Output format quality: type: integer minimum: 1 maximum: 100 default: 95 description: Output quality clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/ai-canvas-expand: post: operationId: aiCanvasExpand tags: [Tools] summary: AI canvas expand (experimental) description: | Expand an image canvas using AI outpainting. Extends the image in any direction by generating new content that blends seamlessly with the original. Uses LaMa-based outpainting. Requires the ai-canvas-expand feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to expand settings: type: string description: | JSON string with options: - `extendTop` (integer >= 0, default 0) - Pixels to extend upward - `extendRight` (integer >= 0, default 0) - Pixels to extend rightward - `extendBottom` (integer >= 0, default 0) - Pixels to extend downward - `extendLeft` (integer >= 0, default 0) - Pixels to extend leftward - `tier` (string, default "balanced") - One of: fast, balanced, high - `format` (string, default "auto") - One of: auto, png, jpg, jpeg, webp, tiff, gif, avif, heic, heif, jxl - `quality` (integer 1-100, default 95) - Output quality At least one extend direction must be greater than 0. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input (or no extend direction > 0) content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/collage: post: operationId: createCollage tags: [Tools] summary: Collage / grid description: Combine multiple images into a grid collage. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Multiple image files to combine settings: type: string description: | JSON string with options: - `templateId` (string, required) - Template ID defining the grid layout - `cells` (array, optional) - Per-cell configuration overrides - `gap` (number 0-500, default 8) - Gap between images in pixels - `cornerRadius` (number 0-500, default 0) - Corner rounding radius - `backgroundColor` (string, default "#FFFFFF") - Background fill color - `aspectRatio` (string, default "free") - Aspect ratio constraint - `outputFormat` (string, default "png") - One of: png, jpeg, webp, avif, jxl - `quality` (number 1-100, default 90) - Output quality responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/stitch: post: operationId: stitchImages tags: [Tools] summary: Stitch images description: Join multiple images horizontally, vertically, or in a grid layout. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Two or more image files to stitch together settings: type: string description: | JSON string with options: - `direction` (string, default "horizontal") - One of: horizontal, vertical, grid - `gridColumns` (integer 2-100, default 2) - Columns when direction is grid - `resizeMode` (string, default "fit") - One of: fit, original, stretch, crop - `alignment` (string, default "center") - One of: start, center, end - `gap` (number 0-1000, default 0) - Gap between images in pixels - `border` (number 0-500, default 0) - Border width in pixels - `cornerRadius` (number 0-500, default 0) - Corner radius in pixels - `backgroundColor` (hex string, default "#FFFFFF") - Hex color for background and gap fill - `format` (string, default "png") - One of: png, jpeg, webp, avif, jxl - `quality` (number 1-100, default 90) - Output quality responses: "200": description: Stitched image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/remove-background: post: operationId: removeBackground tags: [Tools] summary: Remove background description: Remove the background from an image using AI (rembg). Runs locally. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `model` (string, optional) - AI model name - `backgroundType` (string, optional) - One of: transparent, color, gradient, blur, image - `backgroundColor` (string, optional) - Hex color to replace removed background with - `gradientColor1` (string, optional) - First gradient color - `gradientColor2` (string, optional) - Second gradient color - `gradientAngle` (number, optional) - Gradient angle in degrees - `blurEnabled` (boolean, optional) - Enable background blur effect - `blurIntensity` (number 0-100, optional) - Blur strength - `shadowEnabled` (boolean, optional) - Enable drop shadow - `shadowOpacity` (number 0-100, optional) - Shadow opacity clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/remove-background/effects: post: operationId: applyBackgroundEffects tags: [Tools] summary: Apply background effects description: > Apply background replacement or effects to a previously processed remove-background result. Requires a jobId from a prior POST /api/v1/tools/image/remove-background call. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [settings] properties: backgroundImage: type: string format: binary description: Custom background image (required when backgroundType is "image") settings: type: string description: | JSON string with options: - `jobId` (string, required) - Job ID from the initial remove-background call - `filename` (string, required) - Original filename - `backgroundType` (string) - One of: transparent, color, gradient, blur, image - `backgroundColor` (string) - Hex color for solid background - `gradientColor1` (string) - First gradient color - `gradientColor2` (string) - Second gradient color - `gradientAngle` (number) - Gradient angle in degrees - `blurEnabled` (boolean) - Enable background blur effect - `blurIntensity` (number 0-100) - Blur strength - `shadowEnabled` (boolean) - Enable drop shadow - `shadowOpacity` (number 0-100) - Shadow opacity responses: "200": description: Image with applied effects content: application/json: schema: type: object properties: jobId: type: string downloadUrl: type: string processedSize: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/transparency-fixer: post: operationId: fixTransparency tags: [Tools] summary: Fix fake transparency description: | Fix "fake transparent" PNGs that have fringing, halos, or semi-transparent artifacts from a previous background removal. Uses BiRefNet HR-matting (2048x2048) to produce a clean alpha channel with configurable defringe processing. Falls back to birefnet-general, then u2net on OOM. Requires the background-removal feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PNG image with fake or damaged transparency settings: type: string description: | JSON string with options: - `defringe` (number 0-100, default 30) - Edge defringe strength to remove color contamination - `outputFormat` (string, default "png") - One of: png, webp - `removeWatermark` (boolean, default false) - Apply median filter to reduce watermark artifacts before matting clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/upscale: post: operationId: upscaleImage tags: [Tools] summary: Image upscaling description: Upscale an image using AI (Real-ESRGAN). Runs locally. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to upscale settings: type: string description: | JSON string with options: - `scale` (number, default 2) - Upscale factor - `model` (string, default "auto") - AI model name - `faceEnhance` (boolean, default false) - Enable face enhancement - `denoise` (number, default 0) - Denoise strength - `format` (string, default "auto") - Output format (auto, png, jpg, jpeg, webp, tiff, gif, avif, heic, heif, jxl) - `quality` (number, default 95) - Output quality (1-100) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/blur-faces: post: operationId: blurFaces tags: [Tools] summary: Face blur description: Detect and blur faces in an image for privacy. Uses OpenCV. Runs locally. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `blurRadius` (number 1-100, default 30) - Blur strength radius - `sensitivity` (number 0-1, default 0.5) - Face detection sensitivity clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/ocr: post: operationId: extractText tags: [Tools] summary: OCR / text extraction description: Extract text from an image using OCR. Runs locally. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to extract text from settings: type: string description: | JSON string with options: - `quality` (string, default "balanced") - One of: fast, balanced, best - `language` (string, default "auto") - One of: auto, en, de, fr, es, zh, ja, ko - `enhance` (boolean, default true) - Pre-process image for better recognition - `engine` (string, optional) - One of: tesseract, paddleocr (backward compat) clientJobId: type: string responses: "200": description: Extracted text content: application/json: schema: type: object properties: jobId: type: string filename: type: string text: type: string description: Extracted text content engine: type: string "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/info: post: operationId: getImageInfo tags: [Tools] summary: Image info description: Get detailed metadata about an image including dimensions, format, color space, and EXIF data. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to inspect responses: "200": description: Image metadata content: application/json: schema: type: object properties: width: type: integer height: type: integer filename: type: string format: type: string colorSpace: type: string channels: type: integer bitDepth: type: string density: type: [integer, "null"] hasAlpha: type: boolean fileSize: type: integer hasExif: type: boolean isProgressive: type: boolean orientation: type: [integer, "null"] hasProfile: type: boolean hasIcc: type: boolean hasXmp: type: boolean pages: type: integer histogram: type: array items: type: object properties: channel: type: string min: type: number max: type: number mean: type: number stdev: type: number "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/color-palette: post: operationId: extractColorPalette tags: [Tools] summary: Color palette description: Extract the dominant colors from an image. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to analyze responses: "200": description: Dominant colors content: application/json: schema: type: object properties: filename: type: string colors: type: array items: type: string description: Hex color strings count: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/barcode-read: post: operationId: readBarcode tags: [Tools] summary: Barcode reader description: Read QR codes and barcodes from an image. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file containing barcode or QR code settings: type: string description: | JSON string with options: - `tryHarder` (boolean, default true) - Enable more aggressive barcode detection responses: "200": description: Decoded barcode data content: application/json: schema: type: object properties: filename: type: string barcodes: type: array items: type: object properties: type: type: string text: type: string position: type: object properties: topLeft: type: object properties: x: { type: number } y: { type: number } topRight: type: object properties: x: { type: number } y: { type: number } bottomLeft: type: object properties: x: { type: number } y: { type: number } bottomRight: type: object properties: x: { type: number } y: { type: number } annotatedUrl: type: [string, "null"] previewUrl: type: [string, "null"] "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/find-duplicates: post: operationId: findDuplicates tags: [Tools] summary: Find duplicates description: Find duplicate images in a set using perceptual hashing. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Multiple image files to check for duplicates settings: type: string description: | JSON string with options: - `threshold` (number 0-20, default 8) - Hamming distance threshold for duplicate detection responses: "200": description: Duplicate groups content: application/json: schema: type: object properties: totalImages: type: integer duplicateGroups: type: array items: type: object properties: groupId: type: integer files: type: array items: type: object properties: filename: type: string similarity: type: number width: type: integer height: type: integer fileSize: type: integer format: type: string isBest: type: boolean thumbnail: type: [string, "null"] uniqueImages: type: integer spaceSaveable: type: integer skippedFiles: type: array description: Files that could not be processed (present only when non-empty) items: type: object properties: filename: type: string reason: type: string "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/qr-generate: post: operationId: generateQrCode tags: [Tools] summary: QR code generator description: Generate a QR code image from text. This tool accepts a JSON body, not multipart. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [text] properties: text: type: string maxLength: 2000 description: Text to encode in the QR code size: type: integer minimum: 100 maximum: 10000 default: 400 description: Image size in pixels errorCorrection: type: string enum: [L, M, Q, H] default: M foreground: type: string default: "#000000" description: Foreground color (hex) background: type: string default: "#FFFFFF" description: Background color (hex) responses: "200": description: Generated QR code content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/html-to-image: post: operationId: captureWebpage tags: [Tools] summary: Capture webpage as image description: Capture a webpage as a high-quality screenshot image. Accepts a JSON body with a URL and capture options. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [url] properties: url: type: string format: uri description: URL to capture (http/https only) format: type: string enum: [jpg, png, webp] default: png quality: type: integer minimum: 1 maximum: 100 default: 90 fullPage: type: boolean default: false devicePreset: type: string enum: [desktop, tablet, mobile, custom] default: desktop viewportWidth: type: integer minimum: 320 maximum: 3840 default: 1280 viewportHeight: type: integer minimum: 320 maximum: 2160 default: 720 responses: "200": description: Screenshot captured successfully content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid URL or parameters content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "503": description: Browser service unavailable content: application/json: schema: $ref: "#/components/schemas/Error" "504": description: Page load timeout content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/strip-metadata/inspect: post: operationId: inspectMetadata tags: [Tools] summary: Inspect metadata description: View all metadata (EXIF, GPS, ICC, XMP) in an image without removing it. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to inspect responses: "200": description: Image metadata content: application/json: schema: type: object properties: filename: type: string fileSize: type: integer exif: type: object description: EXIF metadata exifError: type: string description: Present when EXIF parsing fails gps: type: object description: GPS metadata icc: type: object description: ICC profile metadata xmp: type: object description: XMP metadata "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Failed to read image metadata content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/edit-metadata: post: operationId: editMetadata tags: [Tools] summary: Edit metadata description: Edit EXIF, IPTC, GPS, and other metadata fields in an image using ExifTool. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `title` (string) - Image title - `author` (string) - Author name - `artist` (string) - Artist or author name - `copyright` (string) - Copyright notice - `imageDescription` (string) - Image description - `software` (string) - Software used - `dateTime` (string) - Date/time string - `dateTimeOriginal` (string) - Original capture date/time - `clearGps` (boolean, default false) - Remove all GPS data - `fieldsToRemove` (string[]) - Specific metadata fields to remove - `gpsLatitude` (number -90 to 90) - GPS latitude - `gpsLongitude` (number -180 to 180) - GPS longitude - `gpsAltitude` (number) - GPS altitude in meters - `keywords` (string[]) - Keywords or tags - `keywordsMode` (string, default "add") - One of: add, set - `dateShift` (string) - Shift dates by offset, e.g. "+2:00" or "-1:30" - `setAllDates` (string) - Set all date fields to this value - `iptcTitle` (string) - IPTC title - `iptcHeadline` (string) - IPTC headline - `iptcCity` (string) - IPTC city - `iptcState` (string) - IPTC state or province - `iptcCountry` (string) - IPTC country responses: "200": description: Image with updated metadata content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/edit-metadata/inspect: post: operationId: inspectMetadataExifTool tags: [Tools] summary: Inspect metadata (ExifTool) description: Read all metadata from an image using ExifTool. Returns all embedded EXIF, IPTC, XMP, and GPS fields. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to inspect responses: "200": description: Full metadata object (keys vary by image) content: application/json: schema: type: object additionalProperties: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Failed to read image metadata content: application/json: schema: $ref: "#/components/schemas/Error" # --- Batch ---------------------------------------------------------------- /api/v1/tools/{section}/{toolId}/batch: post: operationId: batchProcess tags: [Batch] summary: Batch process images description: > Send multiple images through a single tool. Returns a ZIP file. The response includes an X-Job-Id header for progress tracking. security: - bearerAuth: [] parameters: - name: section in: path required: true schema: type: string description: Tool section slug (image, video, audio, pdf, files) - name: toolId in: path required: true schema: type: string description: Tool identifier (e.g. resize, crop) requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Image files to process (one or more) settings: type: string description: JSON string of tool settings applied to all images responses: "200": description: ZIP archive of processed images headers: X-Job-Id: schema: type: string description: Job identifier for progress tracking content: application/zip: schema: type: string format: binary "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" # --- Pipelines ------------------------------------------------------------ /api/v1/pipeline/execute: post: operationId: executePipeline tags: [Pipelines] summary: Execute a pipeline description: Run an image through a chain of tools. The pipeline definition is sent as a JSON string in the `pipeline` multipart field. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file, pipeline] properties: file: type: string format: binary description: Image file to process pipeline: type: string description: 'JSON string: { "steps": [{ "toolId": "resize", "settings": {...} }, ...] }' responses: "200": description: Pipeline result content: application/json: schema: type: object properties: jobId: type: string downloadUrl: type: string originalSize: type: integer processedSize: type: integer stepsCompleted: type: integer steps: type: array items: type: object "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/pipeline/save: post: operationId: savePipeline tags: [Pipelines] summary: Save a pipeline description: Persist a named pipeline definition with its tool steps for later execution. Use this to save reusable workflows. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [name, steps] properties: name: type: string description: type: string description: Optional human-readable description of the pipeline steps: type: array items: type: object properties: toolId: type: string settings: type: object responses: "201": description: Pipeline saved content: application/json: schema: type: object properties: id: type: string name: type: string description: type: string description: Human-readable description of the pipeline steps: type: array items: type: object createdAt: type: string format: date-time "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/pipeline/list: get: operationId: listPipelines tags: [Pipelines] summary: List saved pipelines description: Retrieve all saved pipeline definitions for the current user. Returns name, steps, and creation date for each. security: - bearerAuth: [] responses: "200": description: List of pipelines content: application/json: schema: type: object properties: pipelines: type: array items: type: object properties: id: type: string name: type: string description: type: string description: Human-readable description of the pipeline steps: type: array items: type: object createdAt: type: string format: date-time "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/pipeline/{id}: delete: operationId: deletePipeline tags: [Pipelines] summary: Delete a pipeline description: Permanently delete a saved pipeline by its ID. Only the pipeline owner or an admin can delete it. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Pipeline UUID schema: type: string responses: "200": description: Pipeline deleted content: application/json: schema: type: object properties: ok: type: boolean "403": description: Not authorized to delete this pipeline content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "404": description: Pipeline not found content: application/json: schema: $ref: "#/components/schemas/Error" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/pipeline/tools: get: operationId: listPipelineTools tags: [Pipelines] summary: List pipeline-compatible tools description: Returns all tool IDs that can be used as pipeline steps. security: [] responses: "200": description: Tool IDs content: application/json: schema: type: object properties: toolIds: type: array items: type: string /api/v1/pipeline/batch: post: operationId: batchPipeline tags: [Pipelines] summary: Run pipeline on multiple files description: Execute a pipeline across multiple images. Returns a ZIP file with all processed results. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file, pipeline] properties: file: type: array items: type: string format: binary description: Image files to process pipeline: type: string description: | JSON string with pipeline definition: - `steps` (array, required, 1-20 items) - Pipeline steps - `steps[].toolId` (string, required) - Tool ID for this step - `steps[].settings` (object, optional) - Tool-specific settings clientJobId: type: string description: Optional client-provided job ID for progress tracking via SSE responses: "200": description: ZIP file with processed images headers: X-Job-Id: schema: type: string description: Job ID for progress tracking X-File-Results: schema: type: string description: Percent-encoded JSON mapping of input index to output filename (decode with decodeURIComponent before JSON.parse) content: application/zip: schema: type: string format: binary "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" # --- Files ---------------------------------------------------------------- /api/v1/upload: post: operationId: uploadImage tags: [Files] summary: Upload an image description: Upload a raw image file for later processing by tool endpoints. Returns a jobId and file metadata. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary responses: "200": description: Upload result content: application/json: schema: type: object properties: jobId: type: string files: type: array items: type: object properties: name: type: string size: type: integer format: type: string "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/download/{jobId}/{filename}: get: operationId: downloadProcessedImage tags: [Files] summary: Download a processed image description: Download a processed image by its job ID and filename. This is the URL returned in downloadUrl from tool responses. security: [] parameters: - name: jobId in: path required: true description: Job identifier from a tool processing response schema: type: string - name: filename in: path required: true description: Output filename from the processing response schema: type: string responses: "200": description: Image binary content: image/*: schema: type: string format: binary "404": description: File not found content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/preview: post: operationId: generatePreview tags: [Files] summary: Generate image preview description: Convert any image (including HEIC/HEIF) to a WebP preview, resized to fit within 1200x1200 pixels. security: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to preview responses: "200": description: WebP preview image content: image/webp: schema: type: string format: binary "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/files: get: operationId: listFiles tags: [Files] summary: List saved files description: Returns the latest version of each file (one per version chain). Supports pagination and search. security: - bearerAuth: [] parameters: - name: limit in: query description: Maximum number of files to return (default 50) schema: type: integer default: 50 - name: offset in: query description: Number of files to skip for pagination (default 0) schema: type: integer default: 0 - name: search in: query description: Filter files by original filename (substring match) schema: type: string responses: "200": description: List of saved files content: application/json: schema: type: object properties: files: type: array items: type: object properties: id: type: string filename: type: string size: type: integer contentType: type: string createdAt: type: string format: date-time total: type: integer description: Total number of matching files (for pagination) limit: type: integer description: Applied limit value offset: type: integer description: Applied offset value "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" delete: operationId: bulkDeleteFiles tags: [Files] summary: Bulk delete saved files description: Delete files and their entire version chains. Non-admin users can only delete their own files. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [ids] properties: ids: type: array items: type: string description: File IDs to delete (deletes entire version chain for each) responses: "200": description: Deletion result content: application/json: schema: type: object properties: deleted: type: integer description: Total number of records deleted across all version chains "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/files/upload: post: operationId: saveFileToLibrary tags: [Files] summary: Save file to library description: Upload one or more image files directly to the file library for persistent storage and version tracking. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary responses: "201": description: Files uploaded content: application/json: schema: type: object properties: files: type: array items: type: object description: Full file object with all metadata "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/files/save-result: post: operationId: saveProcessingResult tags: [Files] summary: Save a processing result to library description: Save a tool processing result as a new version of an existing file. Creates a version chain. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file, parentId] properties: file: type: string format: binary description: The processed image file parentId: type: string description: ID of the parent file in the version chain toolId: type: string description: Tool that produced this result responses: "201": description: File saved content: application/json: schema: type: object properties: file: type: object description: Full file object with all metadata "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "404": description: Parent file not found content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/files/{id}: get: operationId: getFile tags: [Files] summary: Get file metadata and version history description: Retrieve metadata and the full version history for a saved file. Use this to inspect file details before downloading. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Saved file UUID schema: type: string responses: "200": description: File metadata with version history content: application/json: schema: type: object properties: file: type: object properties: id: type: string originalName: type: string mimeType: type: string size: type: integer width: type: integer height: type: integer version: type: integer parentId: type: [string, "null"] toolChain: type: array items: type: string createdAt: type: string format: date-time versions: type: array items: type: object description: Full version chain of this file "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "404": description: File not found content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/files/{id}/download: get: operationId: downloadSavedFile tags: [Files] summary: Download a saved file description: Download the binary content of a saved file from the library by its ID. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Saved file UUID schema: type: string responses: "200": description: Image binary content: image/*: schema: type: string format: binary "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "404": description: File not found content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/files/{id}/thumbnail: get: operationId: getFileThumbnail tags: [Files] summary: Get file thumbnail description: Retrieve a 300px JPEG thumbnail of a saved file. Useful for gallery views and file browsers. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Saved file UUID schema: type: string responses: "200": description: 300px JPEG thumbnail content: image/jpeg: schema: type: string format: binary "404": description: File not found content: application/json: schema: $ref: "#/components/schemas/Error" "422": description: Thumbnail generation failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/fetch-urls: post: operationId: fetchImageUrls tags: [Files] summary: Fetch images from URLs description: | Fetch one or more images from external URLs. Each URL is validated against SSRF attacks, size-limited, and verified as a valid image. Returns download URLs for each successfully fetched image. Rate limited to 200 requests per hour. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [urls] properties: urls: type: array items: type: string format: uri minItems: 1 maxItems: 50 description: URLs of images to fetch (1-50) responses: "200": description: Fetch results for each URL content: application/json: schema: type: object properties: results: type: array items: type: object properties: success: type: boolean url: type: string filename: type: string contentType: type: string size: type: integer width: type: integer height: type: integer downloadUrl: type: string previewUrl: type: [string, "null"] error: type: string description: Present only when success is false "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/config/locale: get: operationId: getLocaleConfig tags: [System] summary: Get default locale description: Returns the default locale setting. Public endpoint. security: [] responses: "200": description: Default locale content: application/json: schema: type: object properties: defaultLocale: type: string example: en # --- Auth ----------------------------------------------------------------- /api/auth/login: post: operationId: login tags: [Auth] summary: Log in description: Authenticate with username and password. Returns a bearer token for subsequent API requests. security: [] requestBody: required: true content: application/json: schema: type: object required: [username, password] properties: username: type: string password: type: string format: password responses: "200": description: Login successful content: application/json: schema: type: object properties: token: type: string user: type: object properties: id: type: string username: type: string role: type: string mustChangePassword: type: boolean permissions: type: array items: type: string teamName: type: string expiresAt: type: string format: date-time "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Invalid credentials content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/auth/logout: post: operationId: logout tags: [Auth] summary: Log out description: Invalidate the current session token. The token cannot be used for further requests after logout. security: - bearerAuth: [] responses: "200": description: Logged out content: application/json: schema: type: object properties: ok: type: boolean "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/auth/session: get: operationId: getSession tags: [Auth] summary: Get current session description: Retrieve the current session details including user profile, role, and permissions. Returns null user when not authenticated. security: [] responses: "200": description: Session info content: application/json: schema: type: object properties: user: type: object properties: id: type: string username: type: string role: type: string mustChangePassword: type: boolean permissions: type: array items: type: string expiresAt: type: [string, "null"] format: date-time /api/auth/change-password: post: operationId: changePassword tags: [Auth] summary: Change password description: Change the authenticated user's password. Requires the current password for verification. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [currentPassword, newPassword] properties: currentPassword: type: string format: password newPassword: type: string format: password responses: "200": description: Password changed content: application/json: schema: type: object properties: ok: type: boolean "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/auth/users: get: operationId: listUsers tags: [Auth] summary: List users description: Requires users:manage permission. security: - bearerAuth: [] responses: "200": description: List of users content: application/json: schema: type: object properties: users: type: array items: type: object properties: id: type: string username: type: string role: type: string team: type: string createdAt: type: string format: date-time maxUsers: type: integer "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" /api/auth/register: post: operationId: createUser tags: [Auth] summary: Create user description: Requires users:manage permission. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [username, password] properties: username: type: string password: type: string format: password role: type: string description: Built-in role (admin, editor, user) or custom role name default: user team: type: string default: Default responses: "201": description: User created content: application/json: schema: type: object properties: id: type: string username: type: string role: type: string team: type: string "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "409": description: Username already exists content: application/json: schema: $ref: "#/components/schemas/ConflictError" /api/auth/users/{id}: put: operationId: updateUser tags: [Auth] summary: Update user description: Requires users:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true description: User UUID schema: type: string requestBody: required: true content: application/json: schema: type: object properties: role: type: string description: Built-in role (admin, editor, user) or custom role name team: type: string responses: "200": description: User updated content: application/json: schema: type: object properties: ok: type: boolean "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" delete: operationId: deleteUser tags: [Auth] summary: Delete user description: Requires users:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true description: User UUID schema: type: string responses: "200": description: User deleted content: application/json: schema: type: object properties: ok: type: boolean "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" /api/auth/users/{id}/reset-password: post: operationId: resetUserPassword tags: [Auth] summary: Reset user password description: Requires users:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true description: User UUID schema: type: string requestBody: required: true content: application/json: schema: type: object required: [newPassword] properties: newPassword: type: string format: password responses: "200": description: Password reset content: application/json: schema: type: object properties: ok: type: boolean "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" # --- API Keys ------------------------------------------------------------- /api/v1/api-keys: post: operationId: createApiKey tags: [API Keys] summary: Create an API key description: > Generate a new API key. The full key (prefixed with si_) is returned only once. Keys are stored using scrypt hashing. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: name: type: string maxLength: 100 default: Default API Key permissions: type: array items: type: string description: Scoped permissions for this key expiresAt: type: string format: date-time description: Optional expiration date responses: "201": description: API key created content: application/json: schema: type: object properties: id: type: string key: type: string description: Full key (only shown once) name: type: string permissions: type: [array, "null"] items: type: string expiresAt: type: [string, "null"] format: date-time createdAt: type: string format: date-time "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" get: operationId: listApiKeys tags: [API Keys] summary: List API keys description: Returns key metadata but not the full key. security: - bearerAuth: [] responses: "200": description: List of API keys content: application/json: schema: type: object properties: apiKeys: type: array items: type: object properties: id: type: string name: type: string permissions: type: [array, "null"] items: type: string createdAt: type: string format: date-time lastUsedAt: type: [string, "null"] format: date-time expiresAt: type: [string, "null"] format: date-time "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/api-keys/{id}: delete: operationId: deleteApiKey tags: [API Keys] summary: Delete an API key description: Permanently revoke and delete an API key. The key cannot be used for authentication after deletion. security: - bearerAuth: [] parameters: - name: id in: path required: true description: API key UUID schema: type: string responses: "200": description: API key deleted content: application/json: schema: type: object properties: ok: type: boolean "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" # --- Settings ------------------------------------------------------------- /api/v1/settings: get: operationId: getSettings tags: [Settings] summary: Get all settings description: Retrieve all system settings as key-value pairs. Requires authentication. security: - bearerAuth: [] responses: "200": description: All settings wrapped in a settings object content: application/json: schema: type: object properties: settings: type: object additionalProperties: type: string "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" put: operationId: updateSettings tags: [Settings] summary: Update settings description: Accepts a flat JSON object of key-value pairs to set. Requires admin role. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object additionalProperties: type: string responses: "200": description: Settings updated content: application/json: schema: type: object properties: ok: type: boolean updatedCount: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Admin access required content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" /api/v1/settings/{key}: get: operationId: getSetting tags: [Settings] summary: Get a single setting description: Retrieve a single setting value by its key name. Returns the value and last-updated timestamp. security: - bearerAuth: [] parameters: - name: key in: path required: true description: Setting key name schema: type: string responses: "200": description: Setting value content: application/json: schema: type: object properties: key: type: string value: type: string updatedAt: type: string format: date-time "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "404": description: Setting not found content: application/json: schema: $ref: "#/components/schemas/Error" # --- Teams ---------------------------------------------------------------- /api/v1/teams: get: operationId: listTeams tags: [Teams] summary: List teams description: Requires teams:manage permission. security: - bearerAuth: [] responses: "200": description: List of teams content: application/json: schema: type: object properties: teams: type: array items: type: object properties: id: type: string name: type: string memberCount: type: integer createdAt: type: string format: date-time "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" post: operationId: createTeam tags: [Teams] summary: Create a team description: Requires teams:manage permission. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [name] properties: name: type: string responses: "201": description: Team created content: application/json: schema: type: object properties: id: type: string name: type: string "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "409": description: Team name already exists content: application/json: schema: $ref: "#/components/schemas/ConflictError" /api/v1/teams/{id}: put: operationId: updateTeam tags: [Teams] summary: Rename a team description: Requires teams:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Team UUID schema: type: string requestBody: required: true content: application/json: schema: type: object required: [name] properties: name: type: string responses: "200": description: Team updated content: application/json: schema: type: object properties: ok: type: boolean "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "404": description: Team not found content: application/json: schema: $ref: "#/components/schemas/Error" "409": description: Team name already exists content: application/json: schema: $ref: "#/components/schemas/ConflictError" delete: operationId: deleteTeam tags: [Teams] summary: Delete a team description: Requires teams:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Team UUID schema: type: string responses: "200": description: Team deleted content: application/json: schema: type: object properties: ok: type: boolean "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "404": description: Team not found content: application/json: schema: $ref: "#/components/schemas/Error" # --- System (additional) -------------------------------------------------- /api/v1/config/auth: get: operationId: getAuthConfig tags: [System] summary: Auth configuration description: Check whether authentication is enabled on this instance. Public endpoint used by the frontend to determine login flow. security: [] responses: "200": description: Auth config content: application/json: schema: type: object properties: authEnabled: type: boolean /api/v1/jobs/{jobId}/progress: get: operationId: getJobProgress tags: [System] summary: Job progress (SSE) description: > Server-Sent Events stream for tracking long-running jobs. Closes automatically 5 seconds after completion. security: [] parameters: - name: jobId in: path required: true description: Job UUID from a tool processing or installation response schema: type: string responses: "200": description: > SSE stream of job progress events. Two event types: `single` (single-file tools) and `batch` (batch processing). Single events have `status` and `progress`. Batch events have `completedFiles`, `totalFiles`, `failedFiles` (integers), and an `errors` array. content: text/event-stream: schema: type: object description: > Event shape varies by type. Single: { status, progress }. Batch: { completedFiles, totalFiles, failedFiles, errors }. properties: status: type: string enum: [processing, completed, failed] progress: type: integer minimum: 0 maximum: 100 completedFiles: type: integer description: Number of completed files (batch mode) totalFiles: type: integer description: Total files to process (batch mode) failedFiles: type: integer description: Number of failed files (batch mode) errors: type: array items: type: object properties: filename: type: string error: type: string description: Error details for failed files (batch mode) # --- Admin --------------------------------------------------------------- /api/v1/admin/health: get: operationId: adminHealthCheck tags: [Admin] summary: Admin health check description: | Full system diagnostics including database status, storage mode, queue state, and GPU availability. Requires the system:health permission. security: - bearerAuth: [] responses: "200": description: Detailed system health content: application/json: schema: $ref: "#/components/schemas/AdminHealthResponse" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" # --- Analytics ----------------------------------------------------------- /api/v1/config/analytics: get: operationId: getAnalyticsConfig tags: [Analytics] summary: Get analytics configuration description: | Returns the effective analytics provider configuration. Analytics is enabled only when both the compile-time bake and the instance analyticsEnabled setting allow it. When disabled, the keys, DSN, and instanceId are blank. Public endpoint. security: [] responses: "200": description: Analytics configuration content: application/json: schema: type: object properties: enabled: type: boolean description: | Effective analytics state. True only when both the compile-time bake and the instance analyticsEnabled setting are on. When false, the keys, DSN, and instanceId are blank. posthogApiKey: type: string posthogHost: type: string sentryDsn: type: string sampleRate: type: number instanceId: type: string # --- Features ------------------------------------------------------------ /api/v1/features: get: operationId: listFeatures tags: [Features] summary: List feature bundles description: | Returns all available AI feature bundles and their installation status. In non-Docker environments, all bundles show as installed. security: - bearerAuth: [] responses: "200": description: Feature bundle list content: application/json: schema: type: object properties: bundles: type: array items: type: object properties: id: type: string name: type: string description: type: string description: Human-readable description of the feature bundle status: type: string enum: [installed, not_installed, installing, queued, error] installedVersion: type: [string, "null"] estimatedSize: type: string downloadBytes: type: [integer, "null"] description: >- Compressed archive size for this host's architecture, when the manifest records it. Null in native (non-Docker) mode or when unmeasured. installedBytes: type: [integer, "null"] description: >- Extracted on-disk size for this host's architecture, when the manifest records it. enablesTools: type: array items: type: string progress: type: [object, "null"] properties: percent: type: number stage: type: string error: type: [string, "null"] "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/admin/features/{bundleId}/install: post: operationId: installFeature tags: [Features] summary: Install a feature bundle description: | Start async installation of an AI feature bundle. Downloads models and configures the Python sidecar. Returns a jobId for progress tracking via the SSE endpoint. Requires features:manage permission. Installs are serialized server-side: a request made while another install is running is queued (queued=true) rather than rejected, and starts automatically when the running install finishes. A repeat request for the same in-flight bundle is deduped and returns the same jobId. security: - bearerAuth: [] parameters: - name: bundleId in: path required: true description: Feature bundle identifier schema: type: string responses: "202": description: Installation started or queued content: application/json: schema: type: object properties: jobId: type: string description: Job ID for tracking installation progress via SSE queued: type: boolean description: >- True when the install was queued behind another running install instead of starting immediately. "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "404": description: Unknown bundle ID content: application/json: schema: $ref: "#/components/schemas/Error" "409": description: Bundle already installed content: application/json: schema: $ref: "#/components/schemas/ConflictError" /api/v1/admin/features/{bundleId}/uninstall: post: operationId: uninstallFeature tags: [Features] summary: Uninstall a feature bundle description: | Uninstall an AI feature bundle and delete its model files (unless shared with another installed bundle). Requires features:manage permission. security: - bearerAuth: [] parameters: - name: bundleId in: path required: true description: Feature bundle identifier schema: type: string responses: "200": description: Bundle uninstalled content: application/json: schema: type: object properties: ok: type: boolean "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "404": description: Unknown bundle ID content: application/json: schema: $ref: "#/components/schemas/Error" "409": description: Bundle is not installed content: application/json: schema: $ref: "#/components/schemas/ConflictError" /api/v1/admin/features/disk-usage: get: operationId: getFeatureDiskUsage tags: [Features] summary: AI model disk usage description: | Returns the total disk space used by AI model files. Requires features:manage permission. security: - bearerAuth: [] responses: "200": description: Disk usage content: application/json: schema: type: object properties: totalBytes: type: integer description: Total bytes used by AI model files "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" # --- Audit Log ----------------------------------------------------------- /api/v1/audit-log: get: operationId: queryAuditLog tags: [Audit] summary: Query audit log description: | Paginated audit log of administrative actions. Supports filtering by action type and date range. Requires audit:read permission. security: - bearerAuth: [] parameters: - name: page in: query description: Page number (default 1) schema: type: integer minimum: 1 default: 1 - name: limit in: query description: Results per page (1-100, default 50) schema: type: integer minimum: 1 maximum: 100 default: 50 - name: action in: query description: Filter by action type schema: type: string - name: from in: query description: Filter entries after this ISO 8601 date schema: type: string format: date-time - name: to in: query description: Filter entries before this ISO 8601 date schema: type: string format: date-time responses: "200": description: Paginated audit log entries content: application/json: schema: type: object properties: entries: type: array items: type: object properties: id: type: string actorId: type: [string, "null"] actorUsername: type: string action: type: string targetType: type: [string, "null"] targetId: type: [string, "null"] details: type: [object, "null"] ipAddress: type: [string, "null"] requestId: type: [string, "null"] createdAt: type: string format: date-time total: type: integer description: Total matching entries page: type: integer limit: type: integer "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" # --- Roles --------------------------------------------------------------- /api/v1/roles: get: operationId: listRoles tags: [Roles] summary: List roles description: | List all roles (built-in and custom) with their permissions and user counts. Requires audit:read permission. security: - bearerAuth: [] responses: "200": description: Role list content: application/json: schema: type: object properties: roles: type: array items: type: object properties: id: type: string name: type: string description: type: string description: Human-readable description of the role permissions: type: array items: type: string isBuiltin: type: boolean userCount: type: integer createdAt: type: string format: date-time updatedAt: type: string format: date-time "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" post: operationId: createRole tags: [Roles] summary: Create a custom role description: | Create a new custom role with specified permissions. Role names must be 2-30 characters, lowercase alphanumeric with hyphens and underscores. Requires security:manage permission. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [name, permissions] properties: name: type: string minLength: 2 maxLength: 30 pattern: "^[a-z0-9_-]+$" description: Lowercase role name description: type: string description: Human-readable description permissions: type: array items: type: string description: | Permission strings. Valid values: 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, security:manage responses: "201": description: Role created content: application/json: schema: type: object properties: id: type: string name: type: string description: type: string description: Human-readable description of the role permissions: type: array items: type: string isBuiltin: type: boolean "400": description: Validation error content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "409": description: Role name already exists content: application/json: schema: $ref: "#/components/schemas/ConflictError" /api/v1/roles/{id}: put: operationId: updateRole tags: [Roles] summary: Update a custom role description: | Update name, description, or permissions of a custom role. Built-in roles cannot be modified. Requires security:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Role UUID schema: type: string requestBody: required: true content: application/json: schema: type: object properties: name: type: string minLength: 2 maxLength: 30 description: type: string description: Updated description for the role permissions: type: array items: type: string responses: "200": description: Role updated content: application/json: schema: type: object properties: ok: type: boolean "400": description: Validation error or cannot modify built-in role content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "404": description: Role not found content: application/json: schema: $ref: "#/components/schemas/Error" "409": description: Role name already exists content: application/json: schema: $ref: "#/components/schemas/ConflictError" delete: operationId: deleteRole tags: [Roles] summary: Delete a custom role description: | Delete a custom role. Users assigned to this role are reassigned to the default "user" role. Built-in roles cannot be deleted. Requires security:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Role UUID schema: type: string responses: "200": description: Role deleted content: application/json: schema: type: object properties: ok: type: boolean "400": description: Cannot delete built-in role content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "403": description: Insufficient permissions content: application/json: schema: $ref: "#/components/schemas/ForbiddenError" "404": description: Role not found content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/convert-video: post: operationId: convertVideo tags: [Tools] summary: Convert Video description: Convert videos between MP4, MOV, WebM, AVI, and MKV. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `format` (string, default "mp4") - One of: mp4, mov, webm, avi, mkv - `quality` (string, default "balanced") - One of: high, balanced, small clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/compress-video: post: operationId: compressVideo tags: [Tools] summary: Compress Video description: Shrink video file size with quality control. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `quality` (string, default "balanced") - One of: light, balanced, strong - `resolution` (string, default "original") - One of: original, 1080p, 720p, 480p clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/trim-video: post: operationId: trimVideo tags: [Tools] summary: Trim Video description: Cut a clip out of a video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `startS` (number >= 0, default 0) - Start time in seconds - `endS` (number, required) - End time in seconds (must be after startS) - `precise` (boolean, default false) - Re-encode for frame-accurate cuts instead of keyframe seek responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/mute-video: post: operationId: muteVideo tags: [Tools] summary: Mute Video description: Remove the audio track from a video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/video-to-gif: post: operationId: videoToGif tags: [Tools] summary: Video to GIF description: Turn a video clip into an animated GIF. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `fps` (integer 1-30, default 12) - Output frame rate - `width` (integer 64-1280, default 480) - Output width in pixels - `startS` (number >= 0, default 0) - Start time in seconds - `durationS` (number 0-60, default 5) - Duration in seconds clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/resize-video: post: operationId: resizeVideo tags: [Tools] summary: Resize Video description: Scale a video to a new resolution or preset size. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `width` (integer 16-7680, optional) - Target width in pixels - `height` (integer 16-4320, optional) - Target height in pixels - `preset` (string, default "custom") - One of: custom, 2160p, 1440p, 1080p, 720p, 480p, 360p. When "custom", at least width or height is required responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/crop-video: post: operationId: cropVideo tags: [Tools] summary: Crop Video description: Crop a region out of a video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `width` (integer >= 16, required) - Crop region width in pixels - `height` (integer >= 16, required) - Crop region height in pixels - `x` (integer >= 0, default 0) - Horizontal offset from top-left - `y` (integer >= 0, default 0) - Vertical offset from top-left responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/rotate-video: post: operationId: rotateVideo tags: [Tools] summary: Rotate Video description: Rotate or flip a video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `transform` (string, required) - One of: cw90, ccw90, 180, hflip, vflip responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/change-fps: post: operationId: changeFps tags: [Tools] summary: Change FPS description: Change the frame rate of a video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `fps` (number 1-120, default 30) - Target frame rate responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/video-color: post: operationId: videoColor tags: [Tools] summary: Video Color description: Adjust brightness, contrast, saturation, and gamma. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `brightness` (number -1 to 1, default 0) - Brightness adjustment - `contrast` (number 0-4, default 1) - Contrast multiplier - `saturation` (number 0-3, default 1) - Saturation multiplier - `gamma` (number 0.1-10, default 1) - Gamma correction responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/video-speed: post: operationId: videoSpeed tags: [Tools] summary: Video Speed description: Speed up or slow down a video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `factor` (number 0.25-4, default 2) - Speed multiplier (2 = double speed, 0.5 = half speed) - `keepPitch` (boolean, default true) - Preserve audio pitch when changing speed responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/reverse-video: post: operationId: reverseVideo tags: [Tools] summary: Reverse Video description: Play a video clip backwards. Limited to clips up to 5 minutes. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/video-loudnorm: post: operationId: videoLoudnorm tags: [Tools] summary: Normalize Audio description: Normalize video audio volume to broadcast standard (EBU R128). security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/aspect-pad: post: operationId: aspectPad tags: [Tools] summary: Aspect Pad description: Add solid-color bars to fit a target aspect ratio. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `target` (string, default "9:16") - One of: 16:9, 9:16, 1:1, 4:3, 3:4 - `color` (string, default "#000000") - Hex color for padding bars (e.g. "#000000") responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/blur-pad: post: operationId: blurPad tags: [Tools] summary: Blur Pad description: Fill bars with a blurred copy of the video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `target` (string, default "16:9") - One of: 16:9, 9:16, 1:1, 4:3, 3:4 - `blur` (number 2-50, default 20) - Gaussian blur sigma for the background responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/watermark-video: post: operationId: watermarkVideo tags: [Tools] summary: Watermark Video description: Burn a text watermark onto video frames. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `text` (string, required) - Watermark text (1-200 characters) - `position` (string, default "br") - One of: tl, tc, tr, l, c, r, bl, bc, br - `fontSize` (integer 8-120, default 36) - Font size in pixels - `opacity` (number 0.05-1, default 0.5) - Watermark opacity - `color` (string, default "#ffffff") - Hex color for the text (e.g. "#ffffff") responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/stabilize-video: post: operationId: stabilizeVideo tags: [Tools] summary: Stabilize Video description: Reduce camera shake with two-pass stabilization. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `smoothing` (integer 5-60, default 15) - Smoothing window size in frames clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/gif-to-video: post: operationId: gifToVideo tags: [Tools] summary: GIF to Video description: Convert an animated GIF into an MP4, WebM, or MOV video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: GIF file to convert settings: type: string description: | JSON string with options: - `format` (string, default "mp4") - One of: mp4, webm, mov responses: "200": description: Converted video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/video-to-webp: post: operationId: videoToWebp tags: [Tools] summary: Video to WebP description: Convert a video clip into an animated WebP image. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `fps` (integer 1-30, default 12) - Output frame rate - `width` (integer 16-1920, default 480) - Output width in pixels - `quality` (integer 1-100, default 75) - WebP compression quality - `loop` (boolean, default true) - Loop the animation responses: "200": description: Converted animated WebP content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/video-to-frames: post: operationId: videoToFrames tags: [Tools] summary: Video to Frames description: Extract frames from a video as a ZIP of images. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process settings: type: string description: | JSON string with options: - `mode` (string, default "all") - One of: all, nth, timestamps - `n` (integer 2-1000, default 10) - Extract every Nth frame (used when mode is "nth") - `timestamps` (string, default "") - Comma-separated timestamps in seconds (required when mode is "timestamps") - `format` (string, default "png") - One of: png, jpg responses: "200": description: ZIP archive containing extracted frames content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/merge-videos: post: operationId: mergeVideos tags: [Tools] summary: Merge Videos description: | Join multiple video clips into one MP4 file. All inputs are normalized to the first video's resolution and 30 fps. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Two or more video files to merge (up to 10) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/replace-audio: post: operationId: replaceAudio tags: [Tools] summary: Replace Audio description: Swap the audio track of a video with another file. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: A video file followed by an audio file (exactly 2 files) responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/burn-subtitles: post: operationId: burnSubtitles tags: [Tools] summary: Burn Subtitles description: Permanently render subtitles onto video frames. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: A video file followed by a subtitle file (.srt, .vtt, .ass) settings: type: string description: | JSON string with options: - `fontSize` (integer 8-72, default 24) - Subtitle font size in pixels clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/embed-subtitles: post: operationId: embedSubtitles tags: [Tools] summary: Embed Subtitles description: Mux a subtitle track into the video container. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: A video file followed by a subtitle file (.srt, .vtt, .ass) settings: type: string description: | JSON string with options: - `language` (string, default "eng") - ISO 639-2/B language code (3 lowercase letters, e.g. "eng", "fra", "deu") responses: "200": description: Processed video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/extract-subtitles: post: operationId: extractSubtitles tags: [Tools] summary: Extract Subtitles description: Pull the subtitle track out of a video as an SRT file. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file with an embedded subtitle track responses: "200": description: Extracted subtitle file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/images-to-video: post: operationId: imagesToVideo tags: [Tools] summary: Images to Video description: Turn a set of images into a slideshow video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Two or more image files (up to 60) settings: type: string description: | JSON string with options: - `secondsPerImage` (number 0.5-10, default 2) - Display duration per image in seconds - `resolution` (string, default "720p") - One of: 1080p, 720p, square - `fps` (integer 10-60, default 30) - Output frame rate responses: "200": description: Generated slideshow video content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/video-metadata: post: operationId: videoMetadata tags: [Tools] summary: Clean Video Metadata description: Strip metadata from a video and report what was found. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to process responses: "200": description: Processed video with metadata report content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/video/auto-subtitles: post: operationId: autoSubtitles tags: [Tools] summary: Auto Subtitles description: | AI-powered subtitle generation from video audio tracks using faster-whisper. Supports auto-detection and 10 explicit languages. Requires the transcription feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to transcribe settings: type: string description: | JSON string with options: - `language` (string, default "auto") - One of: auto, en, de, fr, es, zh, ja, ko, id, th, vi - `format` (string, default "srt") - One of: srt, vtt clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/video/extract-audio: post: operationId: extractAudio tags: [Tools] summary: Extract Audio description: Pull the audio track out of a video. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Video file to extract audio from settings: type: string description: | JSON string with options: - `format` (string, default "mp3") - One of: mp3, wav, m4a, ogg responses: "200": description: Extracted audio file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/convert-audio: post: operationId: convertAudio tags: [Tools] summary: Convert Audio description: Convert audio between MP3, WAV, OGG, and more. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `format` (string, default "mp3") - One of: mp3, wav, ogg, flac, m4a - `bitrateKbps` (integer 32-320, default 192) - Output bitrate in kbps responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/trim-audio: post: operationId: trimAudio tags: [Tools] summary: Trim Audio description: Cut a section out of an audio file. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `startS` (number, min 0, default 0) - Start time in seconds - `endS` (number, required) - End time in seconds (must be after start) responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/volume-adjust: post: operationId: volumeAdjust tags: [Tools] summary: Volume Adjust description: Increase or decrease audio volume by a fixed gain. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `gainDb` (number -30 to 30, default 3) - Volume adjustment in decibels responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/normalize-audio: post: operationId: normalizeAudio tags: [Tools] summary: Normalize Audio description: Even out loudness to broadcast standard levels (EBU R128, -16 LUFS). security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/fade-audio: post: operationId: fadeAudio tags: [Tools] summary: Fade Audio description: Add fade-in and fade-out effects to audio. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `fadeInS` (number 0-30, default 1) - Fade-in duration in seconds - `fadeOutS` (number 0-30, default 1) - Fade-out duration in seconds responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/reverse-audio: post: operationId: reverseAudio tags: [Tools] summary: Reverse Audio description: Play audio backwards. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/audio-speed: post: operationId: audioSpeed tags: [Tools] summary: Audio Speed description: Speed up or slow down audio playback. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `factor` (number 0.25-4, default 1.5) - Speed multiplier (0.25 = quarter speed, 4 = quadruple speed) responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/pitch-shift: post: operationId: pitchShift tags: [Tools] summary: Pitch Shift description: Raise or lower pitch by semitones without changing speed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `semitones` (integer -12 to 12, default 3) - Semitones to shift (must be nonzero) responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/audio-channels: post: operationId: audioChannels tags: [Tools] summary: Audio Channels description: Convert between mono, stereo, or swap left and right channels. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `mode` (string, required) - One of: stereo-to-mono, mono-to-stereo, swap responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/silence-removal: post: operationId: removeSilence tags: [Tools] summary: Silence Removal description: Strip silent sections from audio. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `thresholdDb` (number -80 to -20, default -50) - Silence threshold in dB - `minSilenceS` (number 0.1-5, default 0.5) - Minimum silence duration in seconds to remove responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/noise-reduction: post: operationId: reduceNoise tags: [Tools] summary: Noise Reduction description: Reduce background noise with FFT-based denoising. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `strength` (string, default "medium") - One of: light, medium, strong responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/merge-audio: post: operationId: mergeAudio tags: [Tools] summary: Merge Audio description: Combine multiple audio files into one sequential track. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Two or more audio files to merge (max 10) settings: type: string description: | JSON string with options: - `format` (string, default "mp3") - One of: mp3, wav, flac, m4a responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/split-audio: post: operationId: splitAudio tags: [Tools] summary: Split Audio description: | Split audio by time, equal parts, or silence detection. Returns a ToolResponse with a downloadUrl pointing to a ZIP archive of segments. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to split settings: type: string description: | JSON string with options: - `mode` (string, default "time") - One of: time, parts, silence - `segmentS` (number 1-3600, default 60) - Segment length in seconds (mode=time) - `parts` (integer 2-20, default 2) - Number of equal parts (mode=parts) - `thresholdDb` (number -80 to -20, default -40) - Silence threshold in dB (mode=silence) - `minSilenceS` (number 0.1-10, default 0.3) - Minimum silence gap in seconds (mode=silence) responses: "200": description: Processed audio (downloadUrl points to a ZIP archive) content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/ringtone-maker: post: operationId: ringtoneMaker tags: [Tools] summary: Ringtone Maker description: Create a ringtone clip (.m4r) from any audio file. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `startS` (number, min 0, default 0) - Start time in seconds - `durationS` (number 1-30, default 30) - Clip duration in seconds responses: "200": description: Processed audio content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/waveform-image: post: operationId: waveformImage tags: [Tools] summary: Waveform Image description: Generate a waveform visualization as a PNG image from an audio file. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `width` (integer 256-3840, default 1024) - Image width in pixels - `height` (integer 64-1080, default 256) - Image height in pixels - `color` (string, default "#4f46e5") - Waveform hex color (e.g. "#4f46e5") responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/audio-metadata: post: operationId: audioMetadata tags: [Tools] summary: Audio Metadata description: | View, edit, or strip audio tags (ID3). The response includes a `metadata` object with container, durationS, bitrateKbps, and tags alongside the standard ToolResponse fields. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to process settings: type: string description: | JSON string with options: - `strip` (boolean, default false) - Remove all existing metadata - `title` (string, optional, max 500) - Set the title tag - `artist` (string, optional, max 500) - Set the artist tag - `album` (string, optional, max 500) - Set the album tag responses: "200": description: Processed audio with metadata content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/audio/transcribe-audio: post: operationId: transcribeAudio tags: [Tools] summary: Transcribe Audio description: | AI-powered speech-to-text transcription using faster-whisper. Outputs plain text, SRT, or VTT subtitle formats. Requires the transcription feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Audio file to transcribe settings: type: string description: | JSON string with options: - `language` (string, default "auto") - One of: auto, en, de, fr, es, zh, ja, ko, id, th, vi - `outputFormat` (string, default "txt") - One of: txt, srt, vtt clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/pdf/merge-pdf: post: operationId: mergePdf tags: [Tools] summary: Merge PDFs description: Combine multiple PDFs into one. Requires at least two files. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Two or more PDF files to merge (max 20) responses: "200": description: Merged PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/split-pdf: post: operationId: splitPdf tags: [Tools] summary: Split PDF description: | Extract pages or split into parts. In "range" mode returns a single PDF with the selected pages. In "every" mode splits into chunks of N pages and returns a ZIP archive containing the parts. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to split settings: type: string description: | JSON string with options: - `mode` (string, default "range") - One of: range, every - `range` (string, optional) - Page range in qpdf syntax, e.g. "1-5,8,10-z" (required when mode is "range") - `everyN` (integer 1-500, optional) - Split into chunks of N pages (required when mode is "every") responses: "200": description: Split PDF or ZIP archive of parts content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/compress-pdf: post: operationId: compressPdf tags: [Tools] summary: Compress PDF description: | Shrink PDF file size by downsampling embedded images. In "quality" mode a 1-100 slider controls image DPI. In "targetSize" mode a binary search finds the highest DPI that fits the target. If compression would enlarge the file, the original bytes are returned unchanged. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to compress settings: type: string description: | JSON string with options: - `mode` (string, default "quality") - One of: quality, targetSize - `quality` (integer 1-100, optional) - Compression quality (higher = less compression). Used in quality mode - `targetSizeKb` (number, optional) - Target file size in kilobytes. Used in targetSize mode responses: "200": description: Compressed PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/rotate-pdf: post: operationId: rotatePdf tags: [Tools] summary: Rotate PDF description: Rotate pages in a PDF by 90, 180, or 270 degrees. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process settings: type: string description: | JSON string with options: - `angle` (integer, default 90) - One of: 90, 180, 270 - `range` (string, default "1-z") - Page range in qpdf syntax, e.g. "1-5,8" ("1-z" = all pages) responses: "200": description: Rotated PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/extract-pages: post: operationId: extractPages tags: [Tools] summary: Extract pages description: Pull selected pages into a new PDF. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to extract from settings: type: string description: | JSON string with options: - `range` (string, required) - Page range in qpdf syntax, e.g. "1-5,8,10-z" responses: "200": description: Extracted pages as a new PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/remove-pages: post: operationId: removePages tags: [Tools] summary: Remove pages description: Delete specific pages from a PDF. Cannot remove every page. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process settings: type: string description: | JSON string with options: - `pages` (string, required) - Page range to remove in qpdf syntax, e.g. "3,5-7" responses: "200": description: PDF with pages removed content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/organize-pdf: post: operationId: organizePdf tags: [Tools] summary: Organize PDF description: Reorder pages with an explicit page order. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to reorganize settings: type: string description: | JSON string with options: - `order` (string, required) - Desired page order in qpdf syntax, e.g. "3,1,2,5-z" responses: "200": description: Reorganized PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/protect-pdf: post: operationId: protectPdf tags: [Tools] summary: Protect PDF description: Add password protection with AES-256 encryption. Passwords are redacted from audit logs. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to protect settings: type: string description: | JSON string with options: - `userPassword` (string 1-256 chars, required) - Password required to open the PDF - `ownerPassword` (string 1-256 chars, optional) - Owner password for permissions; defaults to userPassword if omitted responses: "200": description: Encrypted PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/unlock-pdf: post: operationId: unlockPdf tags: [Tools] summary: Unlock PDF description: Remove password protection from a PDF. The correct password must be provided. Passwords are redacted from audit logs. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Password-protected PDF file settings: type: string description: | JSON string with options: - `password` (string 1-256 chars, required) - Password to decrypt the PDF responses: "200": description: Decrypted PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/repair-pdf: post: operationId: repairPdf tags: [Tools] summary: Repair PDF description: Attempt to repair a damaged or corrupted PDF. Structural validation is skipped on input to allow malformed files. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Damaged PDF file to repair responses: "200": description: Repaired PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/linearize-pdf: post: operationId: linearizePdf tags: [Tools] summary: Web-optimize PDF description: Linearize a PDF for fast web viewing (progressive download). security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to linearize responses: "200": description: Linearized PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/grayscale-pdf: post: operationId: grayscalePdf tags: [Tools] summary: Grayscale PDF description: Convert all colors in a PDF to grayscale. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to convert responses: "200": description: Grayscale PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/pdfa-convert: post: operationId: pdfaConvert tags: [Tools] summary: PDF/A convert description: Convert a PDF to archival PDF/A-2 format for long-term preservation. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to convert responses: "200": description: PDF/A-2 compliant file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/crop-pdf: post: operationId: cropPdf tags: [Tools] summary: Crop PDF description: Crop all pages with a uniform margin. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to crop settings: type: string description: | JSON string with options: - `margin` (number 0-2000, default 20) - Uniform crop margin in points responses: "200": description: Cropped PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/nup-pdf: post: operationId: nupPdf tags: [Tools] summary: N-up PDF description: Arrange multiple pages per sheet (e.g. 2-up, 4-up). security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process settings: type: string description: | JSON string with options: - `perSheet` (integer, default 2) - One of: 2, 3, 4, 8, 9, 12, 16 responses: "200": description: N-up PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/booklet-pdf: post: operationId: bookletPdf tags: [Tools] summary: Booklet PDF description: Arrange pages for folding into a booklet (impose for duplex printing). security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process settings: type: string description: | JSON string with options: - `perSheet` (integer, default 2) - One of: 2, 4, 6, 8 responses: "200": description: Booklet-imposed PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/watermark-pdf: post: operationId: watermarkPdf tags: [Tools] summary: Watermark PDF description: Add a text watermark to every page of a PDF. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to watermark settings: type: string description: | JSON string with options: - `text` (string 1-200 chars, required) - Watermark text - `position` (string, default "c") - One of: tl, tc, tr, l, c, r, bl, bc, br - `fontSize` (integer 6-72, default 48) - Font size in points - `opacity` (number 0.05-1, default 0.3) - Watermark opacity - `rotation` (number -180 to 180, default 45) - Rotation angle in degrees responses: "200": description: Watermarked PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/pdf-page-numbers: post: operationId: pdfPageNumbers tags: [Tools] summary: PDF page numbers description: Add page numbers ("Page N of M") to every page of a PDF. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process settings: type: string description: | JSON string with options: - `position` (string, default "bc") - One of: bl, bc, br, tl, tc, tr - `fontSize` (integer 6-24, default 10) - Font size in points responses: "200": description: PDF with page numbers content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/convert-document: post: operationId: convertDocument tags: [Tools] summary: Convert document description: Convert between Word, OpenDocument, RTF, and plain text formats. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Document file to convert (.docx, .doc, .odt, .rtf, .txt) settings: type: string description: | JSON string with options: - `format` (string, required) - One of: docx, odt, rtf, txt clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/convert-presentation: post: operationId: convertPresentation tags: [Tools] summary: Convert presentation description: Convert between PowerPoint and OpenDocument presentation formats. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Presentation file to convert (.pptx, .ppt, .odp) settings: type: string description: | JSON string with options: - `format` (string, required) - One of: pptx, odp clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/convert-spreadsheet: post: operationId: convertSpreadsheet tags: [Tools] summary: Convert spreadsheet description: Convert between Excel, OpenDocument, and CSV formats. Multi-sheet workbooks export the first sheet to CSV. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Spreadsheet file to convert (.xlsx, .xls, .ods, .csv) settings: type: string description: | JSON string with options: - `format` (string, required) - One of: xlsx, ods, csv clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/excel-to-pdf: post: operationId: excelToPdf tags: [Tools] summary: Excel to PDF description: Convert spreadsheets to PDF. Wide sheets may paginate across multiple pages. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Spreadsheet file to convert (.xlsx, .xls, .ods, .csv) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/word-to-pdf: post: operationId: wordToPdf tags: [Tools] summary: Word to PDF description: Convert Word documents to PDF. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Word document to convert (.docx, .doc, .odt, .rtf, .txt) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/powerpoint-to-pdf: post: operationId: powerpointToPdf tags: [Tools] summary: PowerPoint to PDF description: Convert presentations to PDF. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Presentation file to convert (.pptx, .ppt, .odp) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/html-to-pdf: post: operationId: htmlToPdf tags: [Tools] summary: HTML to PDF description: Convert an HTML file to PDF. Remote resources are disabled for privacy. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: HTML file to convert (.html, .htm) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/markdown-to-docx: post: operationId: markdownToDocx tags: [Tools] summary: Markdown to Word description: Convert a Markdown file to a Word document (DOCX). security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Markdown file to convert (.md, .markdown) responses: "200": description: Processed document content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/markdown-to-html: post: operationId: markdownToHtml tags: [Tools] summary: Markdown to HTML description: Convert a Markdown file to a standalone HTML page. Remote images in the source are left as-is in the output. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Markdown file to convert (.md, .markdown) responses: "200": description: Processed document content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/markdown-to-pdf: post: operationId: markdownToPdf tags: [Tools] summary: Markdown to PDF description: Convert a Markdown file to a styled PDF. Remote resources are disabled for privacy. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Markdown file to convert (.md, .markdown) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/epub-convert: post: operationId: epubConvert tags: [Tools] summary: Convert EPUB description: Convert an EPUB to PDF, DOCX, HTML, or Markdown. Remote resources inside the book are not fetched. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: EPUB file to convert (.epub) settings: type: string description: | JSON string with options: - `format` (string, required) - One of: pdf, docx, html, md clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/to-epub: post: operationId: toEpub tags: [Tools] summary: Convert to EPUB description: Convert Word, Markdown, HTML, or plain text files to EPUB. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Document file to convert (.docx, .md, .html, .txt) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/flatten-pdf: post: operationId: flattenPdf tags: [Tools] summary: Flatten PDF description: Bake forms and annotations into page content. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process (.pdf) responses: "200": description: Processed PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/redact-pdf: post: operationId: redactPdf tags: [Tools] summary: Redact PDF description: Permanently remove text occurrences (verified true redaction). security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process (.pdf) settings: type: string description: | JSON string with options: - `terms` (string[], required) - Text strings to redact (1-50 terms, each up to 200 characters) - `caseSensitive` (boolean, default false) - Whether matching is case-sensitive responses: "200": description: Processed PDF content: application/json: schema: allOf: - $ref: "#/components/schemas/ToolResponse" - type: object properties: found: type: integer description: Number of redacted occurrences found "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/pdf-to-text: post: operationId: pdfToText tags: [Tools] summary: PDF to text description: Extract plain text from a PDF. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process (.pdf) responses: "200": description: Extracted text file content: application/json: schema: allOf: - $ref: "#/components/schemas/ToolResponse" - type: object properties: chars: type: integer description: Number of characters extracted "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/pdf-to-word: post: operationId: pdfToWord tags: [Tools] summary: PDF to Word description: Best for text-based PDFs; scanned pages need OCR. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to convert (.pdf) clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/pdf-metadata: post: operationId: pdfMetadata tags: [Tools] summary: PDF metadata description: Read and write PDF document metadata. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process (.pdf) settings: type: string description: | JSON string with options: - `title` (string, optional, max 500) - Document title - `author` (string, optional, max 500) - Document author - `subject` (string, optional, max 500) - Document subject - `keywords` (string, optional, max 500) - Document keywords responses: "200": description: Processed PDF with updated metadata content: application/json: schema: allOf: - $ref: "#/components/schemas/ToolResponse" - type: object properties: metadata: type: object description: The resulting PDF metadata fields "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/pdf/ocr-pdf: post: operationId: ocrPdf tags: [Tools] summary: PDF OCR description: | AI-powered OCR to extract text from PDF documents. Supports multiple quality tiers and languages. Requires the OCR feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: PDF file to process (.pdf) settings: type: string description: | JSON string with options: - `quality` (string, default "balanced") - One of: fast, balanced, best - `language` (string, default "auto") - One of: auto, en, de, fr, es, zh, ja, ko - `pages` (string, default "all") - Page selection, e.g. "all", "1-3", "1,3,5" clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/files/chart-maker: post: operationId: chartMaker tags: [Tools] summary: Chart Maker description: Create bar, line, or pie charts from CSV or JSON data. Returns a PNG image. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: CSV or JSON data file settings: type: string description: | JSON string with options: - `kind` (string, default "bar") - One of: bar, line, pie - `title` (string, optional) - Chart title (max 120 characters) - `width` (integer 320-2048, default 960) - Chart width in pixels - `height` (integer 240-1536, default 540) - Chart height in pixels responses: "200": description: Generated chart image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/csv-excel: post: operationId: csvExcel tags: [Tools] summary: CSV to Excel description: Convert between CSV and Excel (XLSX), both directions. Upload a CSV or TSV file to get XLSX, or upload an XLSX file to get CSV. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: CSV, TSV, or XLSX file to convert settings: type: string description: | JSON string with options: - `sheet` (integer, min 1, default 1) - Worksheet number to export when converting from XLSX responses: "200": description: Converted file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/csv-json: post: operationId: csvJson tags: [Tools] summary: CSV to JSON description: Convert between CSV and JSON, both directions. Upload a CSV or TSV file to get JSON, or upload a JSON array of objects to get CSV. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: CSV, TSV, or JSON file to convert settings: type: string description: | JSON string with options: - `pretty` (boolean, default true) - Pretty-print JSON output with indentation responses: "200": description: Converted file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/json-xml: post: operationId: jsonXml tags: [Tools] summary: JSON to XML description: Convert between JSON and XML, both directions. Upload a JSON file to get XML, or upload an XML file to get JSON. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: JSON or XML file to convert settings: type: string description: | JSON string with options: - `pretty` (boolean, default true) - Pretty-print output with indentation responses: "200": description: Converted file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/split-csv: post: operationId: splitCsv tags: [Tools] summary: Split CSV description: Split a CSV file into smaller files by row count. Returns a ZIP archive containing the parts. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: CSV or TSV file to split settings: type: string description: | JSON string with options: - `rowsPerFile` (integer 1-1000000, default 1000) - Number of data rows per output file - `keepHeader` (boolean, default true) - Repeat the header row in each output file responses: "200": description: ZIP archive containing split CSV parts content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/merge-csvs: post: operationId: mergeCsvs tags: [Tools] summary: Merge CSVs description: Combine multiple CSV or TSV files with matching columns into one merged file. All files must have the same column headers. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Two or more CSV or TSV files to merge (2-20 files) responses: "200": description: Merged CSV file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/yaml-json: post: operationId: yamlJson tags: [Tools] summary: YAML / JSON description: Convert between YAML and JSON, both directions. Upload a YAML file to get JSON, or upload a JSON file to get YAML. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: YAML (.yaml, .yml) or JSON file to convert responses: "200": description: Converted file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/xml-to-csv: post: operationId: xmlToCsv tags: [Tools] summary: XML to CSV description: Extract repeating elements from an XML file into a CSV table. Automatically finds the first array of objects in the XML tree. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: XML file to convert responses: "200": description: Extracted CSV file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/create-zip: post: operationId: createZip tags: [Tools] summary: Create ZIP description: Bundle multiple files into a single ZIP archive. Duplicate filenames are automatically deduplicated. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Two or more files to bundle (2-50 files, any type) responses: "200": description: ZIP archive content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/files/extract-zip: post: operationId: extractZip tags: [Tools] summary: Extract ZIP description: Safely extract files from a ZIP archive with bomb protection. Single-file archives return the file directly; multi-file archives return a flat ZIP. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: ZIP archive to extract responses: "200": description: Extracted file or repackaged ZIP archive content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/background-replace: post: operationId: backgroundReplace tags: [Tools] summary: Background replace description: | AI-powered background replacement. Removes the subject's background and composites it onto a solid color or gradient. Requires the background-removal feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `backgroundType` (string, default "color") - One of: color, gradient - `color` (string, default "#ffffff") - Background hex color (when backgroundType is color) - `gradientColor1` (string, optional) - First gradient hex color - `gradientColor2` (string, optional) - Second gradient hex color - `gradientAngle` (integer 0-360, default 180) - Gradient angle in degrees - `feather` (integer 0-20, default 0) - Edge feathering radius - `format` (string, default "png") - One of: png, webp clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/blur-background: post: operationId: blurBackground tags: [Tools] summary: Blur background description: | AI-powered background blur. Removes the background, blurs the original, and composites the sharp subject on top. Requires the background-removal feature bundle to be installed. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `intensity` (integer 1-100, default 50) - Blur intensity - `feather` (integer 0-20, default 0) - Edge feathering radius - `format` (string, default "png") - One of: png, webp clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/image/barcode-generate: post: operationId: generateBarcode tags: [Tools] summary: Barcode generator description: Generate a barcode image from text. This tool accepts a JSON body, not multipart. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [text] properties: text: type: string minLength: 1 maxLength: 256 description: Text to encode in the barcode type: type: string enum: [code128, ean13, upca, code39, itf14, datamatrix] default: code128 description: Barcode format scale: type: integer minimum: 1 maximum: 8 default: 3 description: Image scale factor includeText: type: boolean default: true description: Whether to render the text below the barcode responses: "200": description: Generated barcode content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/circle-crop: post: operationId: circleCrop tags: [Tools] summary: Circle crop description: Crop an image to a centered circle with transparent corners, optional border, and adjustable zoom/offset. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `zoom` (number 1-5, default 1) - Zoom factor (>=1 crops tighter) - `offsetX` (number 0-1, default 0.5) - Horizontal center position - `offsetY` (number 0-1, default 0.5) - Vertical center position - `borderWidth` (integer 0-200, default 0) - Border width in pixels - `borderColor` (string, default "#ffffff") - Border hex color - `background` (string, default "transparent") - "transparent" or a hex color for corners - `outputSize` (integer 16-4096, optional) - Final square dimension in pixels responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/duotone: post: operationId: duotone tags: [Tools] summary: Duotone description: Apply a two-color duotone effect with custom shadow and highlight colors. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `shadow` (string, default "#1e3a8a") - Shadow hex color - `highlight` (string, default "#fbbf24") - Highlight hex color - `intensity` (integer 0-100, default 100) - Effect intensity (0 = original, 100 = full duotone) responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/image-pad: post: operationId: imagePad tags: [Tools] summary: Image pad description: Pad an image to a target aspect ratio with a solid color, transparent, or blurred background. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `target` (string, default "1:1") - One of: 16:9, 9:16, 1:1, 4:3, 3:4, custom - `ratioW` (integer 1-100, default 1) - Custom ratio width (when target is custom) - `ratioH` (integer 1-100, default 1) - Custom ratio height (when target is custom) - `background` (string, default "color") - One of: color, transparent, blur - `color` (string, default "#ffffff") - Background hex color (when background is color) - `padding` (integer 0-50, default 0) - Extra padding as percentage of canvas responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/pixelate: post: operationId: pixelate tags: [Tools] summary: Pixelate description: Apply a pixelation effect to the full image or a specific rectangular region. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `blockSize` (integer 2-128, default 12) - Pixel block size - `region` (object, optional) - Restrict pixelation to a rectangle: - `left` (integer >= 0) - Left offset in pixels - `top` (integer >= 0) - Top offset in pixels - `width` (integer >= 1) - Region width in pixels - `height` (integer >= 1) - Region height in pixels responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/vignette: post: operationId: vignette tags: [Tools] summary: Vignette description: Add a vignette effect with adjustable strength, color, radius, softness, roundness, and center position. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `strength` (number 0.1-1, default 0.5) - Vignette opacity - `color` (string, default "#000000") - Vignette hex color - `radius` (integer 0-100, default 70) - Outer radius as percentage of half-diagonal - `softness` (integer 0-100, default 50) - Feather softness (higher = more gradual) - `roundness` (integer 0-100, default 100) - 100 = circle, 0 = ellipse matching image aspect ratio - `centerX` (integer 0-100, default 50) - Horizontal center position as percentage - `centerY` (integer 0-100, default 50) - Vertical center position as percentage responses: "200": description: Processed image content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/gif-webp: post: operationId: gifWebp tags: [Tools] summary: GIF/WebP converter description: Convert animated GIF to WebP and vice versa, preserving all frames. Only accepts .gif and .webp inputs. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: GIF or WebP file to convert settings: type: string description: | JSON string with options: - `quality` (integer 1-100, default 80) - Output quality for WebP encoding - `lossless` (boolean, default false) - Use lossless WebP compression - `resizePercent` (integer 10-100, default 100) - Scale the output by percentage responses: "200": description: Converted animation content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/histogram: post: operationId: histogram tags: [Tools] summary: Histogram description: | Generate an RGB histogram chart from an image. Returns a PNG histogram image plus per-channel statistics and raw 256-bin histogram data in the response JSON. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to analyze settings: type: string description: | JSON string with options: - `scale` (string, default "linear") - One of: linear, log responses: "200": description: Histogram image and channel statistics content: application/json: schema: allOf: - $ref: "#/components/schemas/ToolResponse" - type: object properties: bins: type: object description: Raw 256-bin histogram arrays per channel properties: r: type: array items: type: integer g: type: array items: type: integer b: type: array items: type: integer lum: type: array items: type: integer stats: type: object description: Per-channel statistics properties: r: type: object properties: mean: type: integer median: type: integer stdev: type: number g: type: object properties: mean: type: integer median: type: integer stdev: type: number b: type: object properties: mean: type: integer median: type: integer stdev: type: number lum: type: object properties: mean: type: integer median: type: integer stdev: type: number mean: type: object description: Backward-compatible mean values properties: r: type: integer g: type: integer b: type: integer max: type: object description: Backward-compatible max bin values properties: r: type: integer g: type: integer b: type: integer "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/lqip-placeholder: post: operationId: lqipPlaceholder tags: [Tools] summary: LQIP placeholder description: | Generate a tiny low-quality image placeholder. Returns a small image file plus a base64 data URI, ready-to-use HTML img tag, and CSS background snippet in the response JSON. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: Image file to process settings: type: string description: | JSON string with options: - `width` (integer 4-64, default 16) - Target width in pixels - `blur` (number 0-20, default 2) - Blur radius (for blur strategy) - `strategy` (string, default "blur") - One of: blur, pixelate, solid - `format` (string, default "webp") - One of: webp, png, jpeg - `quality` (integer 1-100, default 50) - Output quality responses: "200": description: LQIP placeholder image and data URI content: application/json: schema: allOf: - $ref: "#/components/schemas/ToolResponse" - type: object properties: dataUri: type: string description: Complete data URI (data:mime;base64,...) width: type: integer description: Placeholder width in pixels height: type: integer description: Placeholder height in pixels bytes: type: integer description: Placeholder file size in bytes strategy: type: string description: Strategy used (blur, pixelate, or solid) html: type: string description: Ready-to-use HTML img tag css: type: string description: Ready-to-use CSS background-image snippet "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" /api/v1/tools/image/sprite-sheet: post: operationId: spriteSheet tags: [Tools] summary: Sprite sheet description: | Combine multiple images into a single sprite sheet grid. Accepts 2 to 64 images. Each image is resized to match the first image's dimensions. Returns the sprite sheet image plus frame coordinate metadata. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: Two or more image files to combine (max 64) settings: type: string description: | JSON string with options: - `columns` (integer 1-16, default 4) - Number of columns in the grid - `padding` (integer 0-64, default 0) - Padding between cells in pixels - `background` (string, default "#ffffff") - Background hex color - `format` (string, default "png") - One of: png, webp, jpeg - `quality` (integer 1-100, default 90) - Output quality responses: "200": description: Sprite sheet image with frame metadata content: application/json: schema: allOf: - $ref: "#/components/schemas/ToolResponse" - type: object properties: frames: type: array description: Per-frame coordinates in the sprite sheet items: type: object properties: index: type: integer left: type: integer top: type: integer width: type: integer height: type: integer cols: type: integer description: Number of columns rows: type: integer description: Number of rows cellWidth: type: integer description: Cell width in pixels cellHeight: type: integer description: Cell height in pixels canvasWidth: type: integer description: Total canvas width in pixels canvasHeight: type: integer description: Total canvas height in pixels "400": description: Invalid input content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" # Generated catalog and docs parity paths. Keep in sync with packages/shared/src/constants.ts. /api/v1/tools/image/passport-photo: post: operationId: passportPhotoTool tags: [Tools] summary: "Passport Photo" description: | Guidance endpoint for the two-phase passport photo flow. Use `/api/v1/tools/image/passport-photo/analyze` to analyze an image, then `/api/v1/tools/image/passport-photo/generate` to create the final passport photo. This base route returns a 400 guidance error when the required feature bundles are installed, or 501 when they are missing. security: - bearerAuth: [] responses: "400": description: Use the analyze or generate endpoint content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "501": description: Feature not installed content: application/json: schema: $ref: "#/components/schemas/FeatureNotInstalledError" /api/v1/tools/pdf/sign-pdf: post: operationId: signPdfTool tags: [Tools] summary: Sign PDF description: Stamp one or more signature PNG images onto a PDF using normalized page placements. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file, placements, sig0] properties: file: type: string format: binary description: PDF file to sign sig0: type: string format: binary description: First signature image. Additional signatures use sig1, sig2, and so on. placements: type: string description: JSON array of placement objects with sig, page, x, y, w, and h. Coordinates are page fractions with top-left origin. clientJobId: type: string description: Client-provided job ID for SSE progress tracking fileId: type: string description: Optional file library ID to save the signed result as a new version responses: "200": description: Signed PDF content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/jpg-to-png: post: operationId: jpgToPngTool tags: [Tools] summary: "JPG to PNG" description: | Convert JPG to PNG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "JPG to PNG input file (.jpg, .jpeg)" settings: type: string description: | Dedicated JPG to PNG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/png-to-jpg: post: operationId: pngToJpgTool tags: [Tools] summary: "PNG to JPG" description: | Convert PNG to JPG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PNG to JPG input file (.png)" settings: type: string description: | Dedicated PNG to JPG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/jpg-to-webp: post: operationId: jpgToWebpTool tags: [Tools] summary: "JPG to WebP" description: | Convert JPG to WebP This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "JPG to WebP input file (.jpg, .jpeg)" settings: type: string description: | Dedicated JPG to WebP converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/png-to-webp: post: operationId: pngToWebpTool tags: [Tools] summary: "PNG to WebP" description: | Convert PNG to WebP This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PNG to WebP input file (.png)" settings: type: string description: | Dedicated PNG to WebP converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/webp-to-jpg: post: operationId: webpToJpgTool tags: [Tools] summary: "WebP to JPG" description: | Convert WebP to JPG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "WebP to JPG input file (.webp)" settings: type: string description: | Dedicated WebP to JPG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/webp-to-png: post: operationId: webpToPngTool tags: [Tools] summary: "WebP to PNG" description: | Convert WebP to PNG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "WebP to PNG input file (.webp)" settings: type: string description: | Dedicated WebP to PNG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/jpg-to-avif: post: operationId: jpgToAvifTool tags: [Tools] summary: "JPG to AVIF" description: | Convert JPG to AVIF This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "JPG to AVIF input file (.jpg, .jpeg)" settings: type: string description: | Dedicated JPG to AVIF converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/png-to-avif: post: operationId: pngToAvifTool tags: [Tools] summary: "PNG to AVIF" description: | Convert PNG to AVIF This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PNG to AVIF input file (.png)" settings: type: string description: | Dedicated PNG to AVIF converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/webp-to-avif: post: operationId: webpToAvifTool tags: [Tools] summary: "WebP to AVIF" description: | Convert WebP to AVIF This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "WebP to AVIF input file (.webp)" settings: type: string description: | Dedicated WebP to AVIF converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/heic-to-jpg: post: operationId: heicToJpgTool tags: [Tools] summary: "HEIC to JPG" description: | Convert HEIC to JPG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "HEIC to JPG input file (.heic, .heif)" settings: type: string description: | Dedicated HEIC to JPG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/heic-to-png: post: operationId: heicToPngTool tags: [Tools] summary: "HEIC to PNG" description: | Convert HEIC to PNG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "HEIC to PNG input file (.heic, .heif)" settings: type: string description: | Dedicated HEIC to PNG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/heic-to-avif: post: operationId: heicToAvifTool tags: [Tools] summary: "HEIC to AVIF" description: | Convert HEIC to AVIF This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "HEIC to AVIF input file (.heic, .heif)" settings: type: string description: | Dedicated HEIC to AVIF converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/jpg-to-gif: post: operationId: jpgToGifTool tags: [Tools] summary: "JPG to GIF" description: | Convert JPG to GIF This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "JPG to GIF input file (.jpg, .jpeg)" settings: type: string description: | Dedicated JPG to GIF converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/png-to-gif: post: operationId: pngToGifTool tags: [Tools] summary: "PNG to GIF" description: | Convert PNG to GIF This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PNG to GIF input file (.png)" settings: type: string description: | Dedicated PNG to GIF converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/gif-to-jpg: post: operationId: gifToJpgTool tags: [Tools] summary: "GIF to JPG" description: | Convert GIF to JPG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "GIF to JPG input file (.gif)" settings: type: string description: | Dedicated GIF to JPG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/gif-to-png: post: operationId: gifToPngTool tags: [Tools] summary: "GIF to PNG" description: | Convert GIF to PNG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "GIF to PNG input file (.gif)" settings: type: string description: | Dedicated GIF to PNG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/webp-to-gif: post: operationId: webpToGifTool tags: [Tools] summary: "WebP to GIF" description: | Convert WebP to GIF This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "WebP to GIF input file (.webp)" settings: type: string description: | Dedicated WebP to GIF converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/jpg-to-tiff: post: operationId: jpgToTiffTool tags: [Tools] summary: "JPG to TIFF" description: | Convert JPG to TIFF This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "JPG to TIFF input file (.jpg, .jpeg)" settings: type: string description: | Dedicated JPG to TIFF converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/png-to-tiff: post: operationId: pngToTiffTool tags: [Tools] summary: "PNG to TIFF" description: | Convert PNG to TIFF This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PNG to TIFF input file (.png)" settings: type: string description: | Dedicated PNG to TIFF converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/tiff-to-jpg: post: operationId: tiffToJpgTool tags: [Tools] summary: "TIFF to JPG" description: | Convert TIFF to JPG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "TIFF to JPG input file (.tiff, .tif)" settings: type: string description: | Dedicated TIFF to JPG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/tiff-to-png: post: operationId: tiffToPngTool tags: [Tools] summary: "TIFF to PNG" description: | Convert TIFF to PNG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "TIFF to PNG input file (.tiff, .tif)" settings: type: string description: | Dedicated TIFF to PNG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/psd-to-jpg: post: operationId: psdToJpgTool tags: [Tools] summary: "PSD to JPG" description: | Convert PSD to JPG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PSD to JPG input file (.psd)" settings: type: string description: | Dedicated PSD to JPG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/psd-to-png: post: operationId: psdToPngTool tags: [Tools] summary: "PSD to PNG" description: | Convert PSD to PNG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PSD to PNG input file (.psd)" settings: type: string description: | Dedicated PSD to PNG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/png-to-eps: post: operationId: pngToEpsTool tags: [Tools] summary: "PNG to EPS" description: | Convert PNG to EPS This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PNG to EPS input file (.png)" settings: type: string description: | Dedicated PNG to EPS converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/jpg-to-eps: post: operationId: jpgToEpsTool tags: [Tools] summary: "JPG to EPS" description: | Convert JPG to EPS This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "JPG to EPS input file (.jpg, .jpeg)" settings: type: string description: | Dedicated JPG to EPS converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/eps-to-png: post: operationId: epsToPngTool tags: [Tools] summary: "EPS to PNG" description: | Convert EPS to PNG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "EPS to PNG input file (.eps)" settings: type: string description: | Dedicated EPS to PNG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/eps-to-jpg: post: operationId: epsToJpgTool tags: [Tools] summary: "EPS to JPG" description: | Convert EPS to JPG This is a dedicated conversion preset endpoint backed by `convert`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "EPS to JPG input file (.eps)" settings: type: string description: | Dedicated EPS to JPG converter using the convert pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/png-to-svg: post: operationId: pngToSvgTool tags: [Tools] summary: "PNG to SVG" description: | Convert PNG to SVG This is a dedicated conversion preset endpoint backed by `vectorize`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PNG to SVG input file (.png)" settings: type: string description: | Dedicated PNG to SVG converter using the vectorize pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/jpg-to-svg: post: operationId: jpgToSvgTool tags: [Tools] summary: "JPG to SVG" description: | Convert JPG to SVG This is a dedicated conversion preset endpoint backed by `vectorize`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "JPG to SVG input file (.jpg, .jpeg)" settings: type: string description: | Dedicated JPG to SVG converter using the vectorize pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/tiff-to-svg: post: operationId: tiffToSvgTool tags: [Tools] summary: "TIFF to SVG" description: | Convert TIFF to SVG This is a dedicated conversion preset endpoint backed by `vectorize`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "TIFF to SVG input file (.tiff, .tif)" settings: type: string description: | Dedicated TIFF to SVG converter using the vectorize pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/psd-to-svg: post: operationId: psdToSvgTool tags: [Tools] summary: "PSD to SVG" description: | Convert PSD to SVG This is a dedicated conversion preset endpoint backed by `vectorize`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PSD to SVG input file (.psd)" settings: type: string description: | Dedicated PSD to SVG converter using the vectorize pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/eps-to-svg: post: operationId: epsToSvgTool tags: [Tools] summary: "EPS to SVG" description: | Convert EPS to SVG This is a dedicated conversion preset endpoint backed by `vectorize`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "EPS to SVG input file (.eps)" settings: type: string description: | Dedicated EPS to SVG converter using the vectorize pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/svg-to-png: post: operationId: svgToPngTool tags: [Tools] summary: "SVG to PNG" description: | Convert SVG to PNG This is a dedicated conversion preset endpoint backed by `svg-to-raster`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "SVG to PNG input file (.svg, .svgz)" settings: type: string description: | Dedicated SVG to PNG converter using the svg-to-raster pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/svg-to-jpg: post: operationId: svgToJpgTool tags: [Tools] summary: "SVG to JPG" description: | Convert SVG to JPG This is a dedicated conversion preset endpoint backed by `svg-to-raster`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "SVG to JPG input file (.svg, .svgz)" settings: type: string description: | Dedicated SVG to JPG converter using the svg-to-raster pipeline. Optional settings: quality (number 1-100). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/jpg-to-pdf: post: operationId: jpgToPdfTool tags: [Tools] summary: "JPG to PDF" description: | Convert JPG to PDF This is a dedicated conversion preset endpoint backed by `image-to-pdf`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: "JPG to PDF input files (.jpg, .jpeg)" settings: type: string description: | Dedicated JPG to PDF converter using the image-to-pdf pipeline. Optional settings: pageSize (A4, Letter, A3, A5), orientation (portrait or landscape), margin, targetSize, and collate. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/png-to-pdf: post: operationId: pngToPdfTool tags: [Tools] summary: "PNG to PDF" description: | Convert PNG to PDF This is a dedicated conversion preset endpoint backed by `image-to-pdf`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: "PNG to PDF input files (.png)" settings: type: string description: | Dedicated PNG to PDF converter using the image-to-pdf pipeline. Optional settings: pageSize (A4, Letter, A3, A5), orientation (portrait or landscape), margin, targetSize, and collate. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/heic-to-pdf: post: operationId: heicToPdfTool tags: [Tools] summary: "HEIC to PDF" description: | Convert HEIC to PDF This is a dedicated conversion preset endpoint backed by `image-to-pdf`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: "HEIC to PDF input files (.heic, .heif)" settings: type: string description: | Dedicated HEIC to PDF converter using the image-to-pdf pipeline. Optional settings: pageSize (A4, Letter, A3, A5), orientation (portrait or landscape), margin, targetSize, and collate. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/tiff-to-pdf: post: operationId: tiffToPdfTool tags: [Tools] summary: "TIFF to PDF" description: | Convert TIFF to PDF This is a dedicated conversion preset endpoint backed by `image-to-pdf`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: "TIFF to PDF input files (.tiff, .tif)" settings: type: string description: | Dedicated TIFF to PDF converter using the image-to-pdf pipeline. Optional settings: pageSize (A4, Letter, A3, A5), orientation (portrait or landscape), margin, targetSize, and collate. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/webp-to-pdf: post: operationId: webpToPdfTool tags: [Tools] summary: "WebP to PDF" description: | Convert WebP to PDF This is a dedicated conversion preset endpoint backed by `image-to-pdf`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: "WebP to PDF input files (.webp)" settings: type: string description: | Dedicated WebP to PDF converter using the image-to-pdf pipeline. Optional settings: pageSize (A4, Letter, A3, A5), orientation (portrait or landscape), margin, targetSize, and collate. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/gif-to-pdf: post: operationId: gifToPdfTool tags: [Tools] summary: "GIF to PDF" description: | Convert GIF to PDF This is a dedicated conversion preset endpoint backed by `image-to-pdf`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: "GIF to PDF input files (.gif)" settings: type: string description: | Dedicated GIF to PDF converter using the image-to-pdf pipeline. Optional settings: pageSize (A4, Letter, A3, A5), orientation (portrait or landscape), margin, targetSize, and collate. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/image/eps-to-pdf: post: operationId: epsToPdfTool tags: [Tools] summary: "EPS to PDF" description: | Convert EPS to PDF This is a dedicated conversion preset endpoint backed by `image-to-pdf`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: array items: type: string format: binary description: "EPS to PDF input files (.eps)" settings: type: string description: | Dedicated EPS to PDF converter using the image-to-pdf pipeline. Optional settings: pageSize (A4, Letter, A3, A5), orientation (portrait or landscape), margin, targetSize, and collate. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/pdf/pdf-to-jpg: post: operationId: pdfToJpgTool tags: [Tools] summary: "PDF to JPG" description: | Convert PDF to JPG This is a dedicated conversion preset endpoint backed by `pdf-to-image`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PDF to JPG input file (.pdf)" settings: type: string description: | Dedicated PDF to JPG converter using the pdf-to-image pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/pdf/pdf-to-png: post: operationId: pdfToPngTool tags: [Tools] summary: "PDF to PNG" description: | Convert PDF to PNG This is a dedicated conversion preset endpoint backed by `pdf-to-image`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PDF to PNG input file (.pdf)" settings: type: string description: | Dedicated PDF to PNG converter using the pdf-to-image pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/pdf/pdf-to-tiff: post: operationId: pdfToTiffTool tags: [Tools] summary: "PDF to TIFF" description: | Convert PDF to TIFF This is a dedicated conversion preset endpoint backed by `pdf-to-image`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "PDF to TIFF input file (.pdf)" settings: type: string description: | Dedicated PDF to TIFF converter using the pdf-to-image pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mov-to-mp4: post: operationId: movToMp4Tool tags: [Tools] summary: "MOV to MP4" description: | Convert MOV to MP4 This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MOV to MP4 input file (.mov)" settings: type: string description: | Dedicated MOV to MP4 converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/webm-to-mp4: post: operationId: webmToMp4Tool tags: [Tools] summary: "WEBM to MP4" description: | Convert WEBM to MP4 This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "WEBM to MP4 input file (.webm)" settings: type: string description: | Dedicated WEBM to MP4 converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mkv-to-mp4: post: operationId: mkvToMp4Tool tags: [Tools] summary: "MKV to MP4" description: | Convert MKV to MP4 This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MKV to MP4 input file (.mkv)" settings: type: string description: | Dedicated MKV to MP4 converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/avi-to-mp4: post: operationId: aviToMp4Tool tags: [Tools] summary: "AVI to MP4" description: | Convert AVI to MP4 This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "AVI to MP4 input file (.avi)" settings: type: string description: | Dedicated AVI to MP4 converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mp4-to-mov: post: operationId: mp4ToMovTool tags: [Tools] summary: "MP4 to MOV" description: | Convert MP4 to MOV This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MP4 to MOV input file (.mp4)" settings: type: string description: | Dedicated MP4 to MOV converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mp4-to-webm: post: operationId: mp4ToWebmTool tags: [Tools] summary: "MP4 to WEBM" description: | Convert MP4 to WEBM This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MP4 to WEBM input file (.mp4)" settings: type: string description: | Dedicated MP4 to WEBM converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/webm-to-mov: post: operationId: webmToMovTool tags: [Tools] summary: "WEBM to MOV" description: | Convert WEBM to MOV This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "WEBM to MOV input file (.webm)" settings: type: string description: | Dedicated WEBM to MOV converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mkv-to-mov: post: operationId: mkvToMovTool tags: [Tools] summary: "MKV to MOV" description: | Convert MKV to MOV This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MKV to MOV input file (.mkv)" settings: type: string description: | Dedicated MKV to MOV converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/avi-to-mov: post: operationId: aviToMovTool tags: [Tools] summary: "AVI to MOV" description: | Convert AVI to MOV This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "AVI to MOV input file (.avi)" settings: type: string description: | Dedicated AVI to MOV converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mp4-to-avi: post: operationId: mp4ToAviTool tags: [Tools] summary: "MP4 to AVI" description: | Convert MP4 to AVI This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MP4 to AVI input file (.mp4)" settings: type: string description: | Dedicated MP4 to AVI converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mov-to-avi: post: operationId: movToAviTool tags: [Tools] summary: "MOV to AVI" description: | Convert MOV to AVI This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MOV to AVI input file (.mov)" settings: type: string description: | Dedicated MOV to AVI converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mkv-to-avi: post: operationId: mkvToAviTool tags: [Tools] summary: "MKV to AVI" description: | Convert MKV to AVI This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MKV to AVI input file (.mkv)" settings: type: string description: | Dedicated MKV to AVI converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/avi-to-mkv: post: operationId: aviToMkvTool tags: [Tools] summary: "AVI to MKV" description: | Convert AVI to MKV This is a dedicated conversion preset endpoint backed by `convert-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "AVI to MKV input file (.avi)" settings: type: string description: | Dedicated AVI to MKV converter using the convert-video pipeline. Optional settings: quality (high, balanced, small). The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mp4-to-gif: post: operationId: mp4ToGifTool tags: [Tools] summary: "MP4 to GIF" description: | Convert MP4 to GIF This is a dedicated conversion preset endpoint backed by `video-to-gif`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MP4 to GIF input file (.mp4)" settings: type: string description: | Dedicated MP4 to GIF converter using the video-to-gif pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mov-to-gif: post: operationId: movToGifTool tags: [Tools] summary: "MOV to GIF" description: | Convert MOV to GIF This is a dedicated conversion preset endpoint backed by `video-to-gif`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MOV to GIF input file (.mov)" settings: type: string description: | Dedicated MOV to GIF converter using the video-to-gif pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mkv-to-gif: post: operationId: mkvToGifTool tags: [Tools] summary: "MKV to GIF" description: | Convert MKV to GIF This is a dedicated conversion preset endpoint backed by `video-to-gif`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MKV to GIF input file (.mkv)" settings: type: string description: | Dedicated MKV to GIF converter using the video-to-gif pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/avi-to-gif: post: operationId: aviToGifTool tags: [Tools] summary: "AVI to GIF" description: | Convert AVI to GIF This is a dedicated conversion preset endpoint backed by `video-to-gif`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "AVI to GIF input file (.avi)" settings: type: string description: | Dedicated AVI to GIF converter using the video-to-gif pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/gif-to-mp4: post: operationId: gifToMp4Tool tags: [Tools] summary: "GIF to MP4" description: | Convert GIF to MP4 This is a dedicated conversion preset endpoint backed by `gif-to-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "GIF to MP4 input file (.gif)" settings: type: string description: | Dedicated GIF to MP4 converter using the gif-to-video pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/gif-to-webm: post: operationId: gifToWebmTool tags: [Tools] summary: "GIF to WEBM" description: | Convert GIF to WEBM This is a dedicated conversion preset endpoint backed by `gif-to-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "GIF to WEBM input file (.gif)" settings: type: string description: | Dedicated GIF to WEBM converter using the gif-to-video pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/gif-to-mov: post: operationId: gifToMovTool tags: [Tools] summary: "GIF to MOV" description: | Convert GIF to MOV This is a dedicated conversion preset endpoint backed by `gif-to-video`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "GIF to MOV input file (.gif)" settings: type: string description: | Dedicated GIF to MOV converter using the gif-to-video pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mp4-to-mp3: post: operationId: mp4ToMp3Tool tags: [Tools] summary: "MP4 to MP3" description: | Convert MP4 to MP3 This is a dedicated conversion preset endpoint backed by `extract-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MP4 to MP3 input file (.mp4)" settings: type: string description: | Dedicated MP4 to MP3 converter using the extract-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mov-to-mp3: post: operationId: movToMp3Tool tags: [Tools] summary: "MOV to MP3" description: | Convert MOV to MP3 This is a dedicated conversion preset endpoint backed by `extract-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MOV to MP3 input file (.mov)" settings: type: string description: | Dedicated MOV to MP3 converter using the extract-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mkv-to-mp3: post: operationId: mkvToMp3Tool tags: [Tools] summary: "MKV to MP3" description: | Convert MKV to MP3 This is a dedicated conversion preset endpoint backed by `extract-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MKV to MP3 input file (.mkv)" settings: type: string description: | Dedicated MKV to MP3 converter using the extract-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/webm-to-mp3: post: operationId: webmToMp3Tool tags: [Tools] summary: "WEBM to MP3" description: | Convert WEBM to MP3 This is a dedicated conversion preset endpoint backed by `extract-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "WEBM to MP3 input file (.webm)" settings: type: string description: | Dedicated WEBM to MP3 converter using the extract-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/avi-to-mp3: post: operationId: aviToMp3Tool tags: [Tools] summary: "AVI to MP3" description: | Convert AVI to MP3 This is a dedicated conversion preset endpoint backed by `extract-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "AVI to MP3 input file (.avi)" settings: type: string description: | Dedicated AVI to MP3 converter using the extract-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mp4-to-wav: post: operationId: mp4ToWavTool tags: [Tools] summary: "MP4 to WAV" description: | Convert MP4 to WAV This is a dedicated conversion preset endpoint backed by `extract-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MP4 to WAV input file (.mp4)" settings: type: string description: | Dedicated MP4 to WAV converter using the extract-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mov-to-wav: post: operationId: movToWavTool tags: [Tools] summary: "MOV to WAV" description: | Convert MOV to WAV This is a dedicated conversion preset endpoint backed by `extract-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MOV to WAV input file (.mov)" settings: type: string description: | Dedicated MOV to WAV converter using the extract-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/video/mp4-to-ogg: post: operationId: mp4ToOggTool tags: [Tools] summary: "MP4 to OGG" description: | Convert MP4 to OGG This is a dedicated conversion preset endpoint backed by `extract-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MP4 to OGG input file (.mp4)" settings: type: string description: | Dedicated MP4 to OGG converter using the extract-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/m4a-to-mp3: post: operationId: m4aToMp3Tool tags: [Tools] summary: "M4A to MP3" description: | Convert M4A to MP3 This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "M4A to MP3 input file (.m4a)" settings: type: string description: | Dedicated M4A to MP3 converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/m4a-to-wav: post: operationId: m4aToWavTool tags: [Tools] summary: "M4A to WAV" description: | Convert M4A to WAV This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "M4A to WAV input file (.m4a)" settings: type: string description: | Dedicated M4A to WAV converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/aac-to-mp3: post: operationId: aacToMp3Tool tags: [Tools] summary: "AAC to MP3" description: | Convert AAC to MP3 This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "AAC to MP3 input file (.aac)" settings: type: string description: | Dedicated AAC to MP3 converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/aac-to-wav: post: operationId: aacToWavTool tags: [Tools] summary: "AAC to WAV" description: | Convert AAC to WAV This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "AAC to WAV input file (.aac)" settings: type: string description: | Dedicated AAC to WAV converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/aac-to-flac: post: operationId: aacToFlacTool tags: [Tools] summary: "AAC to FLAC" description: | Convert AAC to FLAC This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "AAC to FLAC input file (.aac)" settings: type: string description: | Dedicated AAC to FLAC converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/ogg-to-mp3: post: operationId: oggToMp3Tool tags: [Tools] summary: "OGG to MP3" description: | Convert OGG to MP3 This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "OGG to MP3 input file (.ogg)" settings: type: string description: | Dedicated OGG to MP3 converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/ogg-to-wav: post: operationId: oggToWavTool tags: [Tools] summary: "OGG to WAV" description: | Convert OGG to WAV This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "OGG to WAV input file (.ogg)" settings: type: string description: | Dedicated OGG to WAV converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/wav-to-mp3: post: operationId: wavToMp3Tool tags: [Tools] summary: "WAV to MP3" description: | Convert WAV to MP3 This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "WAV to MP3 input file (.wav)" settings: type: string description: | Dedicated WAV to MP3 converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/mp3-to-wav: post: operationId: mp3ToWavTool tags: [Tools] summary: "MP3 to WAV" description: | Convert MP3 to WAV This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "MP3 to WAV input file (.mp3)" settings: type: string description: | Dedicated MP3 to WAV converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/audio/flac-to-mp3: post: operationId: flacToMp3Tool tags: [Tools] summary: "FLAC to MP3" description: | Convert FLAC to MP3 This is a dedicated conversion preset endpoint backed by `convert-audio`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "FLAC to MP3 input file (.flac)" settings: type: string description: | Dedicated FLAC to MP3 converter using the convert-audio pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "200": description: Processed file content: application/json: schema: $ref: "#/components/schemas/ToolResponse" "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/tools/files/excel-to-csv: post: operationId: excelToCsvTool tags: [Tools] summary: "Excel to CSV" description: | Convert Excel to CSV This is a dedicated conversion preset endpoint backed by `convert-spreadsheet`. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary description: "Excel to CSV input file (.xlsx, .xls)" settings: type: string description: | Dedicated Excel to CSV converter using the convert-spreadsheet pipeline. The output format is locked by the endpoint. clientJobId: type: string description: Client-provided job ID for SSE progress tracking responses: "202": description: Accepted for async processing. Track progress via SSE at /api/v1/jobs/{jobId}/progress. content: application/json: schema: type: object properties: jobId: type: string async: type: boolean example: true "400": description: Invalid input or settings content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Authentication required content: application/json: schema: $ref: "#/components/schemas/UnauthorizedError" "422": description: Processing failed content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/readyz: get: operationId: readinessCheck tags: [System] summary: Readiness check description: Checks PostgreSQL, Redis, local disk space, and S3 reachability when configured. Public endpoint for load balancers and orchestrators. security: [] responses: "200": description: Instance is ready to receive traffic "503": description: Instance is not ready to receive traffic /api/v1/jobs/{jobId}/cancel: post: operationId: cancelJob tags: [System] summary: Cancel job description: Request cancellation for a queued or running job. security: - bearerAuth: [] parameters: - name: jobId in: path required: true schema: type: string responses: "200": description: Cancellation request result "401": description: Authentication required /api/v1/preferences: get: operationId: getPreferences tags: [Settings] summary: Get user preferences description: Return the current user's per-user preference map. security: - bearerAuth: [] responses: "200": description: Preference map "401": description: Authentication required put: operationId: updatePreferences tags: [Settings] summary: Update user preferences description: Upsert one or more preferences for the current user. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object responses: "200": description: Preferences updated "400": description: Invalid preferences body "401": description: Authentication required /api/auth/mfa/enroll: post: operationId: enrollMfa tags: [Auth] summary: Start MFA enrollment description: Start TOTP MFA enrollment for the current user. Requires the enterprise MFA feature. security: - bearerAuth: [] responses: "200": description: Enrollment URI and recovery codes "401": description: Authentication required "403": description: MFA feature not licensed "409": description: MFA enrollment already enabled or pending /api/auth/mfa/verify: post: operationId: verifyMfaEnrollment tags: [Auth] summary: Verify MFA enrollment description: Confirm pending MFA enrollment with a TOTP code. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [code] properties: code: type: string responses: "200": description: MFA enabled "400": description: No pending enrollment or invalid body "401": description: Invalid TOTP code /api/auth/mfa/complete: post: operationId: completeMfaLogin tags: [Auth] summary: Complete MFA login description: Complete a pending login challenge with a TOTP or recovery code. security: [] requestBody: required: true content: application/json: schema: type: object required: [mfaToken, code] properties: mfaToken: type: string code: type: string responses: "200": description: Session token and user profile "400": description: Invalid request body "401": description: Invalid or expired MFA challenge /api/auth/mfa/disable: post: operationId: disableMfa tags: [Auth] summary: Disable MFA description: Disable MFA for the current user after verifying a TOTP code. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [code] properties: code: type: string responses: "200": description: MFA disabled "400": description: MFA is not enabled or body is invalid "401": description: Authentication required or invalid code /api/auth/users/{id}/mfa/reset: post: operationId: resetUserMfa tags: [Auth] summary: Reset user MFA description: Admin reset of a user's MFA enrollment. Requires users:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: "200": description: MFA reset "401": description: Authentication required "403": description: Insufficient permissions "404": description: User not found /api/auth/oidc/login: get: operationId: oidcLogin tags: [Auth] summary: Start OIDC login description: Redirect to the configured OpenID Connect provider. security: [] responses: "302": description: Redirect to identity provider "500": description: OIDC provider discovery failed /api/auth/oidc/callback: get: operationId: oidcCallback tags: [Auth] summary: OIDC callback description: Complete OIDC authorization code flow and create a session. security: [] responses: "302": description: Redirect to the application /api/auth/saml/metadata: get: operationId: samlMetadata tags: [Auth] summary: SAML metadata description: Return SAML service provider metadata XML. security: [] responses: "200": description: SAML metadata XML /api/auth/saml/login: get: operationId: samlLogin tags: [Auth] summary: Start SAML login description: Redirect to the configured SAML identity provider. security: [] responses: "302": description: Redirect to identity provider /api/auth/saml/callback: post: operationId: samlCallback tags: [Auth] summary: SAML callback description: Assertion consumer service endpoint for SAML login. security: [] responses: "302": description: Redirect to the application /api/v1/files/{id}/preview: get: operationId: getFilePreview tags: [Files] summary: File preview description: Stream or generate a browser-compatible preview for a saved PDF, office document, video, or audio file. security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: "200": description: Preview binary "400": description: Preview not supported "401": description: Authentication required "404": description: File not found "422": description: Could not generate preview /api/v1/preview/generate: post: operationId: generatePreview tags: [Files] summary: Generate upload preview description: Generate an on-demand MP4 or MP3 preview for an uploaded media file. security: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary responses: "200": description: Preview binary "400": description: Unsupported file type or missing file "422": description: Could not generate preview /api/v1/admin/log-level: get: operationId: getLogLevel tags: [Admin] summary: Get log level description: Read the current runtime log level. Requires settings:write permission. security: - bearerAuth: [] responses: "200": description: Current log level "403": description: Insufficient permissions post: operationId: setLogLevel tags: [Admin] summary: Set log level description: Change the runtime log level. Requires settings:write permission. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [level] properties: level: type: string enum: [fatal, error, warn, info, debug, trace, silent] responses: "200": description: New log level "400": description: Invalid log level "403": description: Insufficient permissions /api/v1/metrics: get: operationId: getMetrics tags: [Admin] summary: Prometheus metrics description: Return Prometheus metrics. Requires system:health permission. security: - bearerAuth: [] responses: "200": description: Prometheus text format "403": description: Insufficient permissions /api/v1/admin/support-bundle: get: operationId: getSupportBundle tags: [Admin] summary: Support bundle description: Download a redacted diagnostic support bundle ZIP. Requires system:health permission. security: - bearerAuth: [] responses: "200": description: Support bundle ZIP "403": description: Insufficient permissions /api/v1/admin/usage: get: operationId: getAdminUsage tags: [Admin] summary: Usage dashboard data description: Return local usage dashboard data. Requires audit:read permission. security: - bearerAuth: [] parameters: - name: days in: query required: false schema: type: string responses: "200": description: Usage dashboard data "400": description: Invalid query parameters "403": description: Insufficient permissions /api/v1/admin/backup-status: get: operationId: getBackupStatus tags: [Admin] summary: Backup status description: Return last backup metadata and freshness. Requires system:health permission. security: - bearerAuth: [] responses: "200": description: Backup status "403": description: Insufficient permissions post: operationId: setBackupStatus tags: [Admin] summary: Record backup status description: Record a completed backup. Requires system:health permission. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [type] properties: type: type: string sizeBytes: type: integer notes: type: string responses: "200": description: Backup status recorded "400": description: Invalid backup status "403": description: Insufficient permissions /api/v1/admin/features/import: post: operationId: importFeatureBundle tags: [Features] summary: Import feature bundle description: Import an offline AI bundle archive. Requires features:manage permission. security: - bearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary responses: "200": description: Bundle imported "400": description: Invalid archive "403": description: Insufficient permissions "409": description: Import lock is held /api/v1/enterprise/scim/token: post: operationId: createScimToken tags: [Enterprise] summary: Create SCIM token description: Generate a SCIM bearer token. Requires users:manage permission and the enterprise SCIM feature. security: - bearerAuth: [] responses: "201": description: SCIM token created "403": description: SCIM feature not licensed or insufficient permissions delete: operationId: revokeScimToken tags: [Enterprise] summary: Revoke SCIM token description: Revoke the current SCIM bearer token. Requires users:manage permission and the enterprise SCIM feature. security: - bearerAuth: [] responses: "204": description: SCIM token revoked "403": description: SCIM feature not licensed or insufficient permissions /api/v1/scim/v2/ServiceProviderConfig: get: operationId: getScimServiceProviderConfig tags: [Enterprise] summary: SCIM service provider config description: Public SCIM discovery endpoint. security: [] responses: "200": description: SCIM service provider capabilities /api/v1/scim/v2/Schemas: get: operationId: getScimSchemas tags: [Enterprise] summary: SCIM schemas description: Public SCIM schema discovery endpoint. security: [] responses: "200": description: SCIM schemas /api/v1/scim/v2/ResourceTypes: get: operationId: getScimResourceTypes tags: [Enterprise] summary: SCIM resource types description: Public SCIM resource type discovery endpoint. security: [] responses: "200": description: SCIM resource types /api/v1/scim/v2/Users: get: operationId: listScimUsers tags: [Enterprise] summary: List SCIM users description: List SCIM users. Requires the SCIM bearer token. responses: "200": description: SCIM user list post: operationId: createScimUser tags: [Enterprise] summary: Create SCIM user description: Create a SCIM user. Requires the SCIM bearer token. responses: "201": description: SCIM user created /api/v1/scim/v2/Users/{id}: get: operationId: getScimUser tags: [Enterprise] summary: Get SCIM user description: Get a SCIM user by ID. Requires the SCIM bearer token. parameters: - name: id in: path required: true schema: type: string responses: "200": description: SCIM user put: operationId: updateScimUser tags: [Enterprise] summary: Update SCIM user description: Replace a SCIM user by ID. Requires the SCIM bearer token. parameters: - name: id in: path required: true schema: type: string responses: "200": description: SCIM user updated delete: operationId: deleteScimUser tags: [Enterprise] summary: Delete SCIM user description: Soft deactivate a SCIM user by ID. Requires the SCIM bearer token. parameters: - name: id in: path required: true schema: type: string responses: "200": description: SCIM user deactivated /api/v1/scim/v2/Groups: get: operationId: listScimGroups tags: [Enterprise] summary: List SCIM groups description: List SCIM groups. Requires the SCIM bearer token. responses: "200": description: SCIM group list post: operationId: createScimGroup tags: [Enterprise] summary: Create SCIM group description: Create a SCIM group. Requires the SCIM bearer token. responses: "201": description: SCIM group created /api/v1/scim/v2/Groups/{id}: get: operationId: getScimGroup tags: [Enterprise] summary: Get SCIM group description: Get a SCIM group by ID. Requires the SCIM bearer token. parameters: - name: id in: path required: true schema: type: string responses: "200": description: SCIM group put: operationId: updateScimGroup tags: [Enterprise] summary: Update SCIM group description: Replace a SCIM group by ID. Requires the SCIM bearer token. parameters: - name: id in: path required: true schema: type: string responses: "200": description: SCIM group updated delete: operationId: deleteScimGroup tags: [Enterprise] summary: Delete SCIM group description: Delete a SCIM group by ID. Requires the SCIM bearer token. parameters: - name: id in: path required: true schema: type: string responses: "204": description: SCIM group deleted /api/v1/enterprise/audit/export: get: operationId: exportAuditLog tags: [Enterprise] summary: Export audit log description: Export audit entries as JSON or CSV. Requires audit:read permission and the enterprise audit export feature. security: - bearerAuth: [] responses: "200": description: Audit export "400": description: Invalid query parameters "403": description: Feature not licensed or insufficient permissions /api/v1/enterprise/config/export: get: operationId: exportEnterpriseConfig tags: [Enterprise] summary: Export configuration description: Export redacted instance configuration, custom roles, and teams. Requires system:health permission. security: - bearerAuth: [] responses: "200": description: Configuration export "403": description: Feature not licensed or insufficient permissions /api/v1/enterprise/config/import: post: operationId: importEnterpriseConfig tags: [Enterprise] summary: Import configuration description: Import instance configuration, custom roles, and teams. Requires system:health permission. security: - bearerAuth: [] responses: "200": description: Import result "400": description: Invalid import payload "403": description: Feature not licensed or insufficient permissions /api/v1/enterprise/ip-allowlist: get: operationId: getIpAllowlist tags: [Enterprise] summary: Get IP allowlist description: Read the enterprise IP allowlist. Requires security:manage permission. security: - bearerAuth: [] responses: "200": description: IP allowlist "403": description: Feature not licensed or insufficient permissions put: operationId: updateIpAllowlist tags: [Enterprise] summary: Update IP allowlist description: Update CIDR allowlist entries with self-lockout prevention. Requires security:manage permission. security: - bearerAuth: [] responses: "200": description: IP allowlist updated "400": description: Invalid CIDR entries "403": description: Feature not licensed or insufficient permissions /api/v1/enterprise/legal-hold: get: operationId: listLegalHolds tags: [Enterprise] summary: List legal holds description: List users and teams under legal hold. Requires compliance:manage permission. security: - bearerAuth: [] responses: "200": description: Legal holds "403": description: Feature not licensed or insufficient permissions put: operationId: updateLegalHold tags: [Enterprise] summary: Update legal hold description: Apply or release a legal hold on a user or team. Requires compliance:manage permission. security: - bearerAuth: [] responses: "200": description: Legal hold updated "400": description: Invalid request body "403": description: Feature not licensed or insufficient permissions /api/v1/enterprise/siem/config: get: operationId: getSiemConfig tags: [Enterprise] summary: Get SIEM config description: Read SIEM forwarding configuration. Requires webhooks:manage permission. security: - bearerAuth: [] responses: "200": description: SIEM config "403": description: Feature not licensed or insufficient permissions put: operationId: updateSiemConfig tags: [Enterprise] summary: Update SIEM config description: Update SIEM forwarding configuration. Requires webhooks:manage permission. security: - bearerAuth: [] responses: "200": description: SIEM config updated "400": description: Invalid SIEM config "403": description: Feature not licensed or insufficient permissions /api/v1/enterprise/webhooks: get: operationId: listWebhooks tags: [Enterprise] summary: List webhooks description: List webhook destinations. Requires webhooks:manage permission. security: - bearerAuth: [] responses: "200": description: Webhook destinations "403": description: Feature not licensed or insufficient permissions post: operationId: createWebhook tags: [Enterprise] summary: Create webhook description: Create a webhook destination. Requires webhooks:manage permission. security: - bearerAuth: [] responses: "201": description: Webhook created "400": description: Invalid webhook destination "403": description: Feature not licensed or insufficient permissions /api/v1/enterprise/webhooks/{index}: put: operationId: updateWebhook tags: [Enterprise] summary: Update webhook description: Update a webhook destination by index. Requires webhooks:manage permission. security: - bearerAuth: [] parameters: - name: index in: path required: true schema: type: string responses: "200": description: Webhook updated "400": description: Invalid index or destination "404": description: Webhook not found delete: operationId: deleteWebhook tags: [Enterprise] summary: Delete webhook description: Delete a webhook destination by index. Requires webhooks:manage permission. security: - bearerAuth: [] parameters: - name: index in: path required: true schema: type: string responses: "200": description: Webhook deleted "400": description: Invalid index "404": description: Webhook not found /api/v1/enterprise/webhooks/{index}/test: post: operationId: testWebhook tags: [Enterprise] summary: Test webhook description: Send a test payload to a webhook destination. Requires webhooks:manage permission. security: - bearerAuth: [] parameters: - name: index in: path required: true schema: type: string responses: "200": description: Test result "400": description: Invalid index "404": description: Webhook not found /api/v1/enterprise/users/{id}/export: post: operationId: startGdprUserExport tags: [Enterprise] summary: Start GDPR export description: Start a GDPR user data export job. Requires compliance:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: "202": description: Export job started "403": description: Feature not licensed or insufficient permissions "404": description: User not found /api/v1/enterprise/users/{id}/export/{jobId}: get: operationId: getGdprUserExport tags: [Enterprise] summary: Get GDPR export status description: Read status and download URL for a GDPR user export job. Requires compliance:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string - name: jobId in: path required: true schema: type: string responses: "200": description: Export status "404": description: Export job not found /api/v1/enterprise/users/{id}/purge: delete: operationId: purgeEnterpriseUser tags: [Enterprise] summary: Purge user data description: Permanently purge a user's data after explicit confirmation. Requires compliance:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: "200": description: User purged "400": description: Confirmation required "409": description: User or team is under legal hold /api/v1/enterprise/teams/{id}/purge: delete: operationId: purgeEnterpriseTeam tags: [Enterprise] summary: Purge team data description: Permanently purge a team's data after explicit confirmation. Requires compliance:manage permission. security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: "200": description: Team purged "400": description: Confirmation required "409": description: Team is under legal hold /api/v1/admin/version: get: operationId: getAdminVersion tags: [Admin] summary: Version metadata description: Read app version, build date, Node version, and schema version. Requires system:health permission and the enterprise upgrade management feature. security: - bearerAuth: [] responses: "200": description: Version metadata "403": description: Feature not licensed or insufficient permissions /api/v1/admin/migrations/pending: get: operationId: getPendingMigrations tags: [Admin] summary: Migration status description: Compare packaged migrations with applied migrations. Requires system:health permission and the enterprise upgrade management feature. security: - bearerAuth: [] responses: "200": description: Migration status "403": description: Feature not licensed or insufficient permissions /api/v1/admin/upgrade-check: get: operationId: getUpgradeCheck tags: [Admin] summary: Upgrade readiness description: Run upgrade readiness checks. Requires system:health permission and the enterprise upgrade management feature. security: - bearerAuth: [] responses: "200": description: Upgrade readiness result "403": description: Feature not licensed or insufficient permissions /llms.txt: get: operationId: getLlmsTxt tags: [System] summary: LLM summary description: LLM-friendly plain-text API summary generated from the OpenAPI spec. security: [] responses: "200": description: Plain-text LLM summary content: text/plain: schema: type: string /llms-full.txt: get: operationId: getLlmsFullTxt tags: [System] summary: Full LLM API docs description: Complete plain-text API documentation generated from the OpenAPI spec. security: [] responses: "200": description: Full plain-text API docs content: text/plain: schema: type: string /api/v1/openapi.yaml: get: operationId: getOpenApiYaml tags: [System] summary: OpenAPI YAML description: Machine-readable OpenAPI 3.1 specification for this SnapOtter instance. security: [] responses: "200": description: OpenAPI YAML document content: text/yaml: schema: type: string /api/v1/tools/popular: get: operationId: getPopularTools tags: [Tools] summary: Popular tools description: Return up to 12 popular tool IDs, falling back to a curated default list when usage data is sparse. security: [] responses: "200": description: Popular tool IDs content: application/json: schema: type: object properties: tools: type: array items: type: string