diff --git a/apps/docs/.vitepress/config.mts b/apps/docs/.vitepress/config.mts index 7d661aa6..1864ac2d 100644 --- a/apps/docs/.vitepress/config.mts +++ b/apps/docs/.vitepress/config.mts @@ -149,6 +149,9 @@ export default defineConfig({ { text: "Sharpening", link: "/tools/sharpening" }, { text: "Replace & Invert Color", link: "/tools/replace-color" }, { text: "Color Blindness Simulation", link: "/tools/color-blindness" }, + { text: "Duotone", link: "/tools/duotone" }, + { text: "Pixelate", link: "/tools/pixelate" }, + { text: "Vignette", link: "/tools/vignette" }, ], }, { @@ -172,6 +175,9 @@ export default defineConfig({ { text: "HTML to Image", link: "/tools/html-to-image" }, { text: "Barcode Reader", link: "/tools/barcode-read" }, { text: "Image to Base64", link: "/tools/image-to-base64" }, + { text: "Histogram", link: "/tools/histogram" }, + { text: "LQIP Placeholder", link: "/tools/lqip-placeholder" }, + { text: "Barcode Generator", link: "/tools/barcode-generate" }, ], }, { @@ -182,6 +188,9 @@ export default defineConfig({ { text: "Image Splitting", link: "/tools/split" }, { text: "Border & Frame", link: "/tools/border" }, { text: "Beautify Screenshot", link: "/tools/beautify" }, + { text: "Circle Crop", link: "/tools/circle-crop" }, + { text: "Image Pad", link: "/tools/image-pad" }, + { text: "Sprite Sheet", link: "/tools/sprite-sheet" }, ], }, { @@ -190,7 +199,7 @@ export default defineConfig({ { text: "SVG to Raster", link: "/tools/svg-to-raster" }, { text: "Image to SVG", link: "/tools/vectorize" }, { text: "GIF Tools", link: "/tools/gif-tools" }, - { text: "PDF to Image", link: "/tools/pdf-to-image" }, + { text: "GIF/WebP Converter", link: "/tools/gif-webp" }, ], }, { @@ -212,15 +221,121 @@ export default defineConfig({ { text: "Content-Aware Resize", link: "/tools/content-aware-resize" }, { text: "AI Canvas Expand", link: "/tools/ai-canvas-expand" }, { text: "PNG Transparency Fixer", link: "/tools/transparency-fixer" }, + { text: "Background Replace", link: "/tools/background-replace" }, + { text: "Blur Background", link: "/tools/blur-background" }, ], }, { - text: "Video, Audio, Document & Data", + text: "Video", items: [ - { text: "Video tools", link: "/api/rest#video-tools" }, - { text: "Audio tools", link: "/api/rest#audio-tools" }, - { text: "Document tools", link: "/api/rest#document-tools" }, - { text: "Data tools", link: "/api/rest#data-tools" }, + { text: "Convert Video", link: "/tools/convert-video" }, + { text: "Compress Video", link: "/tools/compress-video" }, + { text: "Trim Video", link: "/tools/trim-video" }, + { text: "Mute Video", link: "/tools/mute-video" }, + { text: "Video to GIF", link: "/tools/video-to-gif" }, + { text: "Resize Video", link: "/tools/resize-video" }, + { text: "Crop Video", link: "/tools/crop-video" }, + { text: "Rotate Video", link: "/tools/rotate-video" }, + { text: "Change FPS", link: "/tools/change-fps" }, + { text: "Video Color", link: "/tools/video-color" }, + { text: "Video Speed", link: "/tools/video-speed" }, + { text: "Reverse Video", link: "/tools/reverse-video" }, + { text: "Normalize Audio", link: "/tools/video-loudnorm" }, + { text: "Aspect Pad", link: "/tools/aspect-pad" }, + { text: "Blur Pad", link: "/tools/blur-pad" }, + { text: "Watermark Video", link: "/tools/watermark-video" }, + { text: "Stabilize Video", link: "/tools/stabilize-video" }, + { text: "GIF to Video", link: "/tools/gif-to-video" }, + { text: "Video to WebP", link: "/tools/video-to-webp" }, + { text: "Video to Frames", link: "/tools/video-to-frames" }, + { text: "Merge Videos", link: "/tools/merge-videos" }, + { text: "Replace Audio", link: "/tools/replace-audio" }, + { text: "Burn Subtitles", link: "/tools/burn-subtitles" }, + { text: "Embed Subtitles", link: "/tools/embed-subtitles" }, + { text: "Extract Subtitles", link: "/tools/extract-subtitles" }, + { text: "Images to Video", link: "/tools/images-to-video" }, + { text: "Clean Video Metadata", link: "/tools/video-metadata" }, + { text: "Auto Subtitles", link: "/tools/auto-subtitles" }, + { text: "Extract Audio", link: "/tools/extract-audio" }, + ], + }, + { + text: "Audio", + items: [ + { text: "Convert Audio", link: "/tools/convert-audio" }, + { text: "Trim Audio", link: "/tools/trim-audio" }, + { text: "Volume Adjust", link: "/tools/volume-adjust" }, + { text: "Normalize Audio", link: "/tools/normalize-audio" }, + { text: "Fade Audio", link: "/tools/fade-audio" }, + { text: "Reverse Audio", link: "/tools/reverse-audio" }, + { text: "Audio Speed", link: "/tools/audio-speed" }, + { text: "Pitch Shift", link: "/tools/pitch-shift" }, + { text: "Audio Channels", link: "/tools/audio-channels" }, + { text: "Silence Removal", link: "/tools/silence-removal" }, + { text: "Noise Reduction", link: "/tools/noise-reduction" }, + { text: "Merge Audio", link: "/tools/merge-audio" }, + { text: "Split Audio", link: "/tools/split-audio" }, + { text: "Ringtone Maker", link: "/tools/ringtone-maker" }, + { text: "Waveform Image", link: "/tools/waveform-image" }, + { text: "Audio Metadata", link: "/tools/audio-metadata" }, + { text: "Transcribe Audio", link: "/tools/transcribe-audio" }, + ], + }, + { + text: "PDF & Documents", + items: [ + { text: "PDF to Image", link: "/tools/pdf-to-image" }, + { text: "Merge PDFs", link: "/tools/merge-pdf" }, + { text: "Split PDF", link: "/tools/split-pdf" }, + { text: "Compress PDF", link: "/tools/compress-pdf" }, + { text: "Rotate PDF", link: "/tools/rotate-pdf" }, + { text: "Convert Document", link: "/tools/convert-document" }, + { text: "Convert Presentation", link: "/tools/convert-presentation" }, + { text: "Convert Spreadsheet", link: "/tools/convert-spreadsheet" }, + { text: "Excel to PDF", link: "/tools/excel-to-pdf" }, + { text: "Word to PDF", link: "/tools/word-to-pdf" }, + { text: "Extract Pages", link: "/tools/extract-pages" }, + { text: "Remove Pages", link: "/tools/remove-pages" }, + { text: "Organize PDF", link: "/tools/organize-pdf" }, + { text: "Protect PDF", link: "/tools/protect-pdf" }, + { text: "Unlock PDF", link: "/tools/unlock-pdf" }, + { text: "Repair PDF", link: "/tools/repair-pdf" }, + { text: "Web-Optimize PDF", link: "/tools/linearize-pdf" }, + { text: "Grayscale PDF", link: "/tools/grayscale-pdf" }, + { text: "PDF/A Convert", link: "/tools/pdfa-convert" }, + { text: "Crop PDF", link: "/tools/crop-pdf" }, + { text: "N-up PDF", link: "/tools/nup-pdf" }, + { text: "Booklet PDF", link: "/tools/booklet-pdf" }, + { text: "Watermark PDF", link: "/tools/watermark-pdf" }, + { text: "PDF Page Numbers", link: "/tools/pdf-page-numbers" }, + { text: "Flatten PDF", link: "/tools/flatten-pdf" }, + { text: "Redact PDF", link: "/tools/redact-pdf" }, + { text: "PDF to Text", link: "/tools/pdf-to-text" }, + { text: "PDF to Word", link: "/tools/pdf-to-word" }, + { text: "PDF Metadata", link: "/tools/pdf-metadata" }, + { text: "PowerPoint to PDF", link: "/tools/powerpoint-to-pdf" }, + { text: "HTML to PDF", link: "/tools/html-to-pdf" }, + { text: "Markdown to Word", link: "/tools/markdown-to-docx" }, + { text: "Markdown to HTML", link: "/tools/markdown-to-html" }, + { text: "Markdown to PDF", link: "/tools/markdown-to-pdf" }, + { text: "Convert EPUB", link: "/tools/epub-convert" }, + { text: "Convert to EPUB", link: "/tools/to-epub" }, + { text: "PDF OCR", link: "/tools/ocr-pdf" }, + ], + }, + { + text: "Data", + items: [ + { text: "Chart Maker", link: "/tools/chart-maker" }, + { text: "CSV to Excel", link: "/tools/csv-excel" }, + { text: "CSV to JSON", link: "/tools/csv-json" }, + { text: "JSON to XML", link: "/tools/json-xml" }, + { text: "Split CSV", link: "/tools/split-csv" }, + { text: "Merge CSVs", link: "/tools/merge-csvs" }, + { text: "YAML / JSON", link: "/tools/yaml-json" }, + { text: "XML to CSV", link: "/tools/xml-to-csv" }, + { text: "Create ZIP", link: "/tools/create-zip" }, + { text: "Extract ZIP", link: "/tools/extract-zip" }, ], }, ], diff --git a/apps/docs/tools/aspect-pad.md b/apps/docs/tools/aspect-pad.md new file mode 100644 index 00000000..8cdb308d --- /dev/null +++ b/apps/docs/tools/aspect-pad.md @@ -0,0 +1,46 @@ +--- +description: Add solid-color bars to fit a target aspect ratio. +--- + +# Aspect Pad + +Add solid-color letterbox or pillarbox bars to fit a video into a target aspect ratio without cropping. + +## API Endpoint + +`POST /api/v1/tools/aspect-pad` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| target | string | No | `"9:16"` | Target aspect ratio: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | +| color | string | No | `"#000000"` | Hex color for the padding bars (e.g. `"#000000"` for black) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/aspect-pad \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"target": "1:1", "color": "#ffffff"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 13200000 +} +``` + +## Notes + +- If the video already matches the target aspect ratio, the file is returned unchanged. +- Use `9:16` for vertical/portrait social media formats (TikTok, Reels, Shorts). +- For blurred padding instead of solid color, use the Blur Pad tool. diff --git a/apps/docs/tools/audio-channels.md b/apps/docs/tools/audio-channels.md new file mode 100644 index 00000000..95e72268 --- /dev/null +++ b/apps/docs/tools/audio-channels.md @@ -0,0 +1,46 @@ +--- +description: Convert between mono and stereo or swap left and right channels. +--- + +# Audio Channels + +Convert audio between mono and stereo layouts, or swap the left and right channels of a stereo file. + +## API Endpoint + +`POST /api/v1/tools/audio-channels` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| mode | string | Yes | - | Channel operation: `stereo-to-mono`, `mono-to-stereo`, `swap` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/audio-channels \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"mode": "stereo-to-mono"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 2300000 +} +``` + +## Notes + +- `stereo-to-mono` mixes both channels into a single mono track. +- `mono-to-stereo` duplicates the mono channel to both left and right. +- `swap` exchanges the left and right channels of a stereo file. +- Output format matches the input format. diff --git a/apps/docs/tools/audio-metadata.md b/apps/docs/tools/audio-metadata.md new file mode 100644 index 00000000..c992131f --- /dev/null +++ b/apps/docs/tools/audio-metadata.md @@ -0,0 +1,70 @@ +--- +description: View, edit, or strip audio metadata tags (ID3). +--- + +# Audio Metadata + +View, edit, or strip audio metadata tags such as title, artist, and album (ID3 and similar tag formats). + +## API Endpoint + +`POST /api/v1/tools/audio-metadata` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| strip | boolean | No | `false` | Remove all existing metadata tags | +| title | string | No | - | Set the title tag (max 500 characters) | +| artist | string | No | - | Set the artist tag (max 500 characters) | +| album | string | No | - | Set the album tag (max 500 characters) | + +## Example Request + +Edit metadata tags: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/audio-metadata \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"title": "My Song", "artist": "Artist Name", "album": "Album Name"}' +``` + +Strip all metadata: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/audio-metadata \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"strip": true}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 4480000, + "metadata": { + "container": "mp3", + "durationS": 245.3, + "bitrateKbps": 192, + "tags": { + "title": "My Song", + "artist": "Artist Name", + "album": "Album Name" + } + } +} +``` + +## Notes + +- The response includes a `metadata` object with container format, duration, bitrate, and current tags. +- When `strip` is `true`, all tag fields are ignored and every existing tag is removed. +- Only the tags you provide are updated; unspecified tags remain unchanged. +- Output format matches the input format. diff --git a/apps/docs/tools/audio-speed.md b/apps/docs/tools/audio-speed.md new file mode 100644 index 00000000..a0dbe4ef --- /dev/null +++ b/apps/docs/tools/audio-speed.md @@ -0,0 +1,45 @@ +--- +description: Speed up or slow down audio playback with a multiplier. +--- + +# Audio Speed + +Speed up or slow down audio playback by applying a speed multiplier. + +## API Endpoint + +`POST /api/v1/tools/audio-speed` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| factor | number | No | `1.5` | Speed multiplier (0.25 to 4). Values below 1 slow down; above 1 speed up. | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/audio-speed \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"factor": 2}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 2250000 +} +``` + +## Notes + +- A factor of `0.25` plays at quarter speed (4x longer). A factor of `4` plays at quadruple speed (4x shorter). +- Pitch changes proportionally with speed. Use pitch-shift if you need to adjust pitch independently. +- Output format matches the input format. diff --git a/apps/docs/tools/auto-subtitles.md b/apps/docs/tools/auto-subtitles.md new file mode 100644 index 00000000..3eedc4b5 --- /dev/null +++ b/apps/docs/tools/auto-subtitles.md @@ -0,0 +1,45 @@ +--- +description: Generate subtitle files from video audio tracks using AI. +--- + +# Auto Subtitles + +Generate subtitle files from a video's audio track using AI-powered speech recognition (faster-whisper). Supports auto-detection and 10 explicit languages. + +## API Endpoint + +`POST /api/v1/tools/auto-subtitles` + +Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| language | string | No | `"auto"` | Speech language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | +| format | string | No | `"srt"` | Output subtitle format: `srt`, `vtt` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/auto-subtitles \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"language": "en", "format": "srt"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- This is an AI tool that requires the **transcription** feature bundle to be installed. If the bundle is not installed, the API returns `501 Feature Not Installed` with instructions to install it via the admin UI. +- The `auto` language option uses whisper's built-in language detection. Specifying the language explicitly improves accuracy and speed. +- SRT is the most widely supported subtitle format. VTT (WebVTT) is the standard for web video players. +- Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. diff --git a/apps/docs/tools/background-replace.md b/apps/docs/tools/background-replace.md new file mode 100644 index 00000000..55ee767f --- /dev/null +++ b/apps/docs/tools/background-replace.md @@ -0,0 +1,52 @@ +--- +description: Replace image background with a solid color or gradient using AI. +--- + +# Background Replace + +Replace the background of an image with a solid color or gradient. The AI model detects the subject, removes the original background, and composites the subject onto your chosen background. + +## API Endpoint + +`POST /api/v1/tools/background-replace` + +Accepts multipart form data with an image file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| backgroundType | string | No | `"color"` | Background mode: `color` or `gradient` | +| color | string | No | `"#ffffff"` | Background hex color (when backgroundType is `color`) | +| gradientColor1 | string | No | - | First gradient hex color | +| gradientColor2 | string | No | - | Second gradient hex color | +| gradientAngle | integer | No | `180` | Gradient angle in degrees (0-360) | +| feather | integer | No | `0` | Edge feathering radius (0-20) | +| format | string | No | `"png"` | Output format: `png` or `webp` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/background-replace \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"backgroundType": "color", "color": "#2563eb", "feather": 2}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +Track progress via SSE at `GET /api/v1/jobs/{jobId}/progress`. When the job completes, the SSE stream emits a `completed` event with the download URL. + +## Notes + +- This is an AI-powered tool that returns `202 Accepted` and processes asynchronously. Connect to the SSE endpoint to receive progress updates and the final result. +- Requires the **background-removal** feature bundle to be installed. Returns `501` if the bundle is not available. +- HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. +- Output defaults to PNG to preserve transparency around the subject. diff --git a/apps/docs/tools/barcode-generate.md b/apps/docs/tools/barcode-generate.md new file mode 100644 index 00000000..13b4b88a --- /dev/null +++ b/apps/docs/tools/barcode-generate.md @@ -0,0 +1,49 @@ +--- +description: Generate barcodes in Code 128, EAN-13, UPC-A, Code 39, ITF-14, and Data Matrix formats. +--- + +# Barcode Generator + +Generate barcode images from text input. Supports Code 128, EAN-13, UPC-A, Code 39, ITF-14, and Data Matrix formats. + +## API Endpoint + +`POST /api/v1/tools/barcode-generate` + +Accepts an `application/json` body (not multipart). The barcode is generated from the provided text, not from an uploaded file. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| text | string | Yes | - | Text to encode in the barcode (1-256 characters) | +| type | string | No | `"code128"` | Barcode format: `code128`, `ean13`, `upca`, `code39`, `itf14`, `datamatrix` | +| scale | integer | No | `3` | Image scale factor (1-8) | +| includeText | boolean | No | `true` | Whether to render the text below the barcode | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/barcode-generate \ + -H "Authorization: Bearer si_your-api-key" \ + -H "Content-Type: application/json" \ + -d '{"text": "5901234123457", "type": "ean13", "scale": 4}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/barcode.png", + "originalSize": 0, + "processedSize": 4520 +} +``` + +## Notes + +- Unlike most tools, this endpoint accepts a JSON body, not multipart form data, since barcodes are generated from text rather than an uploaded file. +- EAN-13 requires exactly 12 or 13 digits. UPC-A requires exactly 11 or 12 digits. If a check digit is omitted, it is calculated automatically. +- Code 128 is the most flexible format and supports the full ASCII character set. +- Data Matrix produces a 2D barcode suitable for encoding longer strings in a compact square. diff --git a/apps/docs/tools/blur-background.md b/apps/docs/tools/blur-background.md new file mode 100644 index 00000000..a95e48cb --- /dev/null +++ b/apps/docs/tools/blur-background.md @@ -0,0 +1,48 @@ +--- +description: Blur the background while keeping the subject sharp using AI. +--- + +# Blur Background + +Blur the background of an image while keeping the subject sharp. The AI model isolates the subject, applies a blur to the original background, and composites the sharp subject on top. + +## API Endpoint + +`POST /api/v1/tools/blur-background` + +Accepts multipart form data with an image file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| intensity | integer | No | `50` | Blur intensity (1-100) | +| feather | integer | No | `0` | Edge feathering radius (0-20) | +| format | string | No | `"png"` | Output format: `png` or `webp` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/blur-background \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"intensity": 75, "feather": 3}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +Track progress via SSE at `GET /api/v1/jobs/{jobId}/progress`. When the job completes, the SSE stream emits a `completed` event with the download URL. + +## Notes + +- This is an AI-powered tool that returns `202 Accepted` and processes asynchronously. Connect to the SSE endpoint to receive progress updates and the final result. +- Requires the **background-removal** feature bundle to be installed. Returns `501` if the bundle is not available. +- Higher intensity values produce a stronger blur effect. Values above 80 create a pronounced bokeh-like separation. +- HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. diff --git a/apps/docs/tools/blur-pad.md b/apps/docs/tools/blur-pad.md new file mode 100644 index 00000000..21c0ae0f --- /dev/null +++ b/apps/docs/tools/blur-pad.md @@ -0,0 +1,46 @@ +--- +description: Fill bars with a blurred copy of the video. +--- + +# Blur Pad + +Fit a video into a target aspect ratio by filling the padding area with a blurred, scaled copy of the video instead of solid-color bars. + +## API Endpoint + +`POST /api/v1/tools/blur-pad` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| target | string | No | `"16:9"` | Target aspect ratio: `16:9`, `9:16`, `1:1`, `4:3`, `3:4` | +| blur | number | No | `20` | Gaussian blur sigma for the background (2-50) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/blur-pad \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"target": "16:9", "blur": 30}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 14100000 +} +``` + +## Notes + +- Higher blur values produce a softer, more abstract background. Lower values keep more detail visible. +- If the video already matches the target aspect ratio, the file is returned unchanged. +- For solid-color padding, use the Aspect Pad tool instead. diff --git a/apps/docs/tools/booklet-pdf.md b/apps/docs/tools/booklet-pdf.md new file mode 100644 index 00000000..a9901be7 --- /dev/null +++ b/apps/docs/tools/booklet-pdf.md @@ -0,0 +1,45 @@ +--- +description: Arrange PDF pages for folding into a booklet. +--- + +# Booklet PDF + +Impose pages for duplex printing so the printed sheets can be folded into a booklet. + +## API Endpoint + +`POST /api/v1/tools/booklet-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| perSheet | integer | No | `2` | Pages per sheet: `2`, `4`, `6`, or `8` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/booklet-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"perSheet": 2}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2400000 +} +``` + +## Notes + +- The default `perSheet: 2` places two pages side by side on each sheet, which is the standard booklet layout for duplex printing. +- Blank pages are added automatically if the total page count is not a multiple of the sheet size. +- Print the output double-sided on short-edge binding, then fold and staple. diff --git a/apps/docs/tools/burn-subtitles.md b/apps/docs/tools/burn-subtitles.md new file mode 100644 index 00000000..1e9ce3e2 --- /dev/null +++ b/apps/docs/tools/burn-subtitles.md @@ -0,0 +1,44 @@ +--- +description: Permanently render subtitles onto video frames. +--- + +# Burn Subtitles + +Permanently render (hard-code) subtitles from an SRT, VTT, or ASS file onto every frame of a video. + +## API Endpoint + +`POST /api/v1/tools/burn-subtitles` + +Accepts multipart form data with a video file and a subtitle file. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| fontSize | integer | No | `24` | Subtitle font size in pixels (8-72) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/burn-subtitles \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F "file=@subtitles.srt" \ + -F 'settings={"fontSize": 28}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Upload two files: the first must be a video, the second must be a subtitle file (.srt, .vtt, or .ass). +- Burned subtitles are permanently part of the video and cannot be turned off by the viewer. For toggleable subtitles, use the Embed Subtitles tool instead. +- Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. diff --git a/apps/docs/tools/change-fps.md b/apps/docs/tools/change-fps.md new file mode 100644 index 00000000..07542216 --- /dev/null +++ b/apps/docs/tools/change-fps.md @@ -0,0 +1,45 @@ +--- +description: Change the frame rate of a video. +--- + +# Change FPS + +Change the frame rate of a video to a target value between 1 and 120 fps. + +## API Endpoint + +`POST /api/v1/tools/change-fps` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| fps | number | No | `30` | Target frame rate (1-120) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/change-fps \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"fps": 24}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 10200000 +} +``` + +## Notes + +- Lowering the frame rate drops frames and reduces file size. Increasing it duplicates frames to fill the gap but does not add real motion detail. +- Common target values: 24 (cinema), 30 (web/broadcast), 60 (smooth playback). +- The audio track is preserved at its original sample rate. diff --git a/apps/docs/tools/chart-maker.md b/apps/docs/tools/chart-maker.md new file mode 100644 index 00000000..158b276d --- /dev/null +++ b/apps/docs/tools/chart-maker.md @@ -0,0 +1,49 @@ +--- +description: Create bar, line, or pie charts from CSV or JSON data. +--- + +# Chart Maker + +Create bar, line, or pie charts from CSV or JSON data. Returns a PNG image of the rendered chart. + +## API Endpoint + +`POST /api/v1/tools/chart-maker` + +Accepts multipart form data with a CSV or JSON file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| kind | string | No | `"bar"` | Chart type: `bar`, `line`, `pie` | +| title | string | No | - | Chart title (max 120 characters) | +| width | integer | No | `960` | Chart width in pixels (320--2048) | +| height | integer | No | `540` | Chart height in pixels (240--1536) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/chart-maker \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@sales.csv" \ + -F 'settings={"kind": "line", "title": "Monthly Sales", "width": 960, "height": 540}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sales.png", + "originalSize": 1024, + "processedSize": 48500 +} +``` + +## Notes + +- Input must be a `.csv` or `.json` file. CSV files should have a header row with column names. +- The first column is used as the category axis; remaining numeric columns become data series. +- JSON input should be an array of objects with consistent keys. +- Output is always a PNG image regardless of input format. diff --git a/apps/docs/tools/circle-crop.md b/apps/docs/tools/circle-crop.md new file mode 100644 index 00000000..39c71478 --- /dev/null +++ b/apps/docs/tools/circle-crop.md @@ -0,0 +1,52 @@ +--- +description: Crop an image to a centered circle with transparent corners. +--- + +# Circle Crop + +Crop an image to a centered circle with transparent corners. Supports adjustable zoom, offset, border, and output size. + +## API Endpoint + +`POST /api/v1/tools/circle-crop` + +Accepts multipart form data with an image file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| zoom | number | No | `1` | Zoom factor (1-5); higher values crop tighter | +| offsetX | number | No | `0.5` | Horizontal center position (0-1) | +| offsetY | number | No | `0.5` | Vertical center position (0-1) | +| borderWidth | integer | No | `0` | Border width in pixels (0-200) | +| borderColor | string | No | `"#ffffff"` | Border hex color | +| background | string | No | `"transparent"` | Corner fill: `"transparent"` or a hex color | +| outputSize | integer | No | - | Final square dimension in pixels (16-4096) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/circle-crop \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"zoom": 1.2, "borderWidth": 4, "borderColor": "#333333"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.png", + "originalSize": 2450000, + "processedSize": 185000 +} +``` + +## Notes + +- Output is always PNG to preserve the transparent corners (unless `background` is set to a solid color). +- The circle is inscribed within the shorter dimension of the image. Use `zoom` to crop tighter and `offsetX`/`offsetY` to shift the visible area. +- When `outputSize` is provided, the result is resized to that square dimension after cropping. +- HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. diff --git a/apps/docs/tools/compress-pdf.md b/apps/docs/tools/compress-pdf.md new file mode 100644 index 00000000..d8810619 --- /dev/null +++ b/apps/docs/tools/compress-pdf.md @@ -0,0 +1,59 @@ +--- +description: Shrink PDF file size by compressing embedded images. +--- + +# Compress PDF + +Reduce PDF file size by downsampling embedded images. Choose between a quality slider or a target file size. + +## API Endpoint + +`POST /api/v1/tools/compress-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| mode | string | No | `"quality"` | Compression mode: `quality` or `targetSize` | +| quality | integer | No | - | Compression quality, 1-100 (higher = less compression). Used in `quality` mode | +| targetSizeKb | number | No | - | Target file size in kilobytes. Used in `targetSize` mode | + +## Example Request + +Compress by quality: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/compress-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"mode": "quality", "quality": 60}' +``` + +Compress to a target size: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/compress-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"mode": "targetSize", "targetSizeKb": 500}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 5200000, + "processedSize": 1800000 +} +``` + +## Notes + +- In `quality` mode, lower values produce smaller files with more image degradation. +- In `targetSize` mode, a binary search finds the highest DPI that fits the requested size. +- If compression would enlarge the file, the original bytes are returned unchanged. +- Text and vector content are not affected; only embedded raster images are downsampled. diff --git a/apps/docs/tools/compress-video.md b/apps/docs/tools/compress-video.md new file mode 100644 index 00000000..c6a5883d --- /dev/null +++ b/apps/docs/tools/compress-video.md @@ -0,0 +1,44 @@ +--- +description: Shrink video file size with quality control. +--- + +# Compress Video + +Shrink video file size using configurable compression strength and optional resolution downscaling. + +## API Endpoint + +`POST /api/v1/tools/compress-video` + +Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| quality | string | No | `"balanced"` | Compression strength: `light`, `balanced`, `strong` | +| resolution | string | No | `"original"` | Output resolution: `original`, `1080p`, `720p`, `480p` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/compress-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"quality": "strong", "resolution": "720p"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- The `light` preset preserves near-original quality. The `strong` preset reduces file size aggressively at the cost of visual fidelity. +- Downscaling resolution (e.g. from 4K to 720p) compounds with compression for significant size reduction. +- Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. diff --git a/apps/docs/tools/convert-audio.md b/apps/docs/tools/convert-audio.md new file mode 100644 index 00000000..2d413ea0 --- /dev/null +++ b/apps/docs/tools/convert-audio.md @@ -0,0 +1,46 @@ +--- +description: Convert audio between MP3, WAV, OGG, FLAC, and M4A formats. +--- + +# Convert Audio + +Convert audio files between common formats including MP3, WAV, OGG, FLAC, and M4A, with configurable output bitrate. + +## API Endpoint + +`POST /api/v1/tools/convert-audio` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| format | string | No | `"mp3"` | Output format: `mp3`, `wav`, `ogg`, `flac`, `m4a` | +| bitrateKbps | integer | No | `192` | Output bitrate in kbps (32 to 320) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/convert-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"format": "flac", "bitrateKbps": 256}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.flac", + "originalSize": 4500000, + "processedSize": 8200000 +} +``` + +## Notes + +- Supported input formats include MP3, WAV, OGG, FLAC, AAC, M4A, WMA, AIFF, and OPUS. +- Bitrate only applies to lossy formats (MP3, OGG, M4A). Lossless formats like WAV and FLAC ignore this setting. +- The output filename keeps the original name with the new extension. diff --git a/apps/docs/tools/convert-document.md b/apps/docs/tools/convert-document.md new file mode 100644 index 00000000..e9cb4cd8 --- /dev/null +++ b/apps/docs/tools/convert-document.md @@ -0,0 +1,46 @@ +--- +description: Convert between Word, OpenDocument, RTF, and plain text formats. +--- + +# Convert Document + +Convert documents between Word (DOCX), OpenDocument (ODT), RTF, and plain text formats using LibreOffice. + +## API Endpoint + +`POST /api/v1/tools/convert-document` + +Accepts multipart form data with a Word/ODT/RTF/TXT file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| format | string | Yes | - | Output format: `docx`, `odt`, `rtf`, `txt` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/convert-document \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@report.docx" \ + -F 'settings={"format": "odt"}' +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input formats: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. +- Conversion is handled by LibreOffice running headless on the server. +- Complex formatting (macros, embedded objects) may not survive conversion between formats. +- The output format must differ from the input format. diff --git a/apps/docs/tools/convert-presentation.md b/apps/docs/tools/convert-presentation.md new file mode 100644 index 00000000..252e3bd2 --- /dev/null +++ b/apps/docs/tools/convert-presentation.md @@ -0,0 +1,46 @@ +--- +description: Convert between PowerPoint and OpenDocument presentation formats. +--- + +# Convert Presentation + +Convert presentations between PowerPoint (PPTX) and OpenDocument Presentation (ODP) formats. + +## API Endpoint + +`POST /api/v1/tools/convert-presentation` + +Accepts multipart form data with a PowerPoint/ODP file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| format | string | Yes | - | Output format: `pptx`, `odp` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/convert-presentation \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@slides.pptx" \ + -F 'settings={"format": "odp"}' +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input formats: `.pptx`, `.ppt`, `.odp`. +- Conversion is handled by LibreOffice running headless on the server. +- Animations and transition effects may not be preserved across formats. +- The output format must differ from the input format. diff --git a/apps/docs/tools/convert-spreadsheet.md b/apps/docs/tools/convert-spreadsheet.md new file mode 100644 index 00000000..20510e7d --- /dev/null +++ b/apps/docs/tools/convert-spreadsheet.md @@ -0,0 +1,46 @@ +--- +description: Convert between Excel, OpenDocument, and CSV formats. +--- + +# Convert Spreadsheet + +Convert spreadsheets between Excel (XLSX), OpenDocument Spreadsheet (ODS), and CSV formats. Multi-sheet workbooks export the first sheet when converting to CSV. + +## API Endpoint + +`POST /api/v1/tools/convert-spreadsheet` + +Accepts multipart form data with an Excel/ODS/CSV file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| format | string | Yes | - | Output format: `xlsx`, `ods`, `csv` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/convert-spreadsheet \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@data.xlsx" \ + -F 'settings={"format": "csv"}' +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input formats: `.xlsx`, `.xls`, `.ods`, `.csv`. +- When converting a multi-sheet workbook to CSV, only the first sheet is exported. +- Formulas are evaluated and exported as static values in CSV output. +- The output format must differ from the input format. diff --git a/apps/docs/tools/convert-video.md b/apps/docs/tools/convert-video.md new file mode 100644 index 00000000..98368a1e --- /dev/null +++ b/apps/docs/tools/convert-video.md @@ -0,0 +1,44 @@ +--- +description: Convert videos between MP4, MOV, and WebM. +--- + +# Convert Video + +Convert videos between MP4, MOV, and WebM formats with configurable quality presets. + +## API Endpoint + +`POST /api/v1/tools/convert-video` + +Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| format | string | No | `"mp4"` | Output format: `mp4`, `mov`, `webm` | +| quality | string | No | `"balanced"` | Quality preset: `high`, `balanced`, `small` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/convert-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"format": "webm", "quality": "balanced"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- The `high` quality preset produces the best visual fidelity but larger files. The `small` preset aggressively compresses for minimum file size. +- WebM output uses VP9 encoding. MP4 and MOV use H.264. +- Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. diff --git a/apps/docs/tools/create-zip.md b/apps/docs/tools/create-zip.md new file mode 100644 index 00000000..b3140c50 --- /dev/null +++ b/apps/docs/tools/create-zip.md @@ -0,0 +1,45 @@ +--- +description: Bundle multiple files into a single ZIP archive. +--- + +# Create ZIP + +Bundle multiple files of any type into a single ZIP archive. Duplicate filenames are automatically deduplicated. + +## API Endpoint + +`POST /api/v1/tools/create-zip` + +Accepts multipart form data with two or more files. No settings field is required. + +## Parameters + +This tool has no configurable parameters. Upload 2--50 files of any type to bundle. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/create-zip \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@report.pdf" \ + -F "file=@data.csv" \ + -F "file=@photo.jpg" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", + "originalSize": 3500000, + "processedSize": 2800000 +} +``` + +## Notes + +- Requires between 2 and 50 input files. +- Any file type is accepted; there are no restrictions on input format. +- If multiple files share the same name, they are automatically deduplicated with numeric suffixes. +- The output archive uses standard ZIP compression (deflate). diff --git a/apps/docs/tools/crop-pdf.md b/apps/docs/tools/crop-pdf.md new file mode 100644 index 00000000..bb8d4ff2 --- /dev/null +++ b/apps/docs/tools/crop-pdf.md @@ -0,0 +1,45 @@ +--- +description: Crop all pages of a PDF with a uniform margin. +--- + +# Crop PDF + +Crop all pages of a PDF by applying a uniform margin, trimming content from each edge equally. + +## API Endpoint + +`POST /api/v1/tools/crop-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| margin | number | No | `20` | Uniform crop margin in points (0-2000) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/crop-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"margin": 50}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2440000 +} +``` + +## Notes + +- The margin value is in PDF points (1 point = 1/72 inch). +- The same margin is applied to all four edges of every page. +- A margin of `0` removes all existing crop margins, showing the full media box. diff --git a/apps/docs/tools/crop-video.md b/apps/docs/tools/crop-video.md new file mode 100644 index 00000000..f5f2d30b --- /dev/null +++ b/apps/docs/tools/crop-video.md @@ -0,0 +1,48 @@ +--- +description: Crop a region out of a video. +--- + +# Crop Video + +Crop a rectangular region out of a video by specifying the region's size and position. + +## API Endpoint + +`POST /api/v1/tools/crop-video` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| width | integer | Yes | - | Crop region width in pixels (minimum 16) | +| height | integer | Yes | - | Crop region height in pixels (minimum 16) | +| x | integer | No | `0` | Horizontal offset from the top-left corner | +| y | integer | No | `0` | Vertical offset from the top-left corner | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/crop-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"width": 640, "height": 480, "x": 100, "y": 50}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 5200000 +} +``` + +## Notes + +- The crop region must fit within the video dimensions. If `x + width` or `y + height` exceeds the source size, the request returns a 400 error. +- Minimum crop size is 16x16 pixels. +- Dimensions are rounded to even numbers as required by most video codecs. diff --git a/apps/docs/tools/csv-excel.md b/apps/docs/tools/csv-excel.md new file mode 100644 index 00000000..446d44ce --- /dev/null +++ b/apps/docs/tools/csv-excel.md @@ -0,0 +1,56 @@ +--- +description: Convert between CSV and Excel (XLSX), both directions. +--- + +# CSV to Excel + +Convert between CSV and Excel (XLSX) formats in both directions. Upload a CSV or TSV file to get XLSX, or upload an XLSX file to get CSV. + +## API Endpoint + +`POST /api/v1/tools/csv-excel` + +Accepts multipart form data with a CSV, TSV, or XLSX file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| sheet | integer | No | `1` | Worksheet number to export when converting from XLSX (min 1) | + +## Example Request + +CSV to Excel: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/csv-excel \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@data.csv" \ + -F 'settings={"sheet": 1}' +``` + +Excel to CSV: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/csv-excel \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@report.xlsx" \ + -F 'settings={"sheet": 2}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/data.xlsx", + "originalSize": 2048, + "processedSize": 5120 +} +``` + +## Notes + +- Conversion direction is auto-detected from the input file extension: `.csv` or `.tsv` produces `.xlsx`, and `.xlsx` produces `.csv`. +- The `sheet` parameter only applies when converting from XLSX. It selects which worksheet to export. +- TSV (tab-separated values) files are supported alongside CSV. diff --git a/apps/docs/tools/csv-json.md b/apps/docs/tools/csv-json.md new file mode 100644 index 00000000..4a0b2366 --- /dev/null +++ b/apps/docs/tools/csv-json.md @@ -0,0 +1,57 @@ +--- +description: Convert between CSV and JSON, both directions. +--- + +# CSV to JSON + +Convert between CSV and JSON formats in both directions. Upload a CSV or TSV file to get a JSON array of objects, or upload a JSON array to get a CSV file. + +## API Endpoint + +`POST /api/v1/tools/csv-json` + +Accepts multipart form data with a CSV, TSV, or JSON file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| pretty | boolean | No | `true` | Pretty-print JSON output with indentation | + +## Example Request + +CSV to JSON: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/csv-json \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@users.csv" \ + -F 'settings={"pretty": true}' +``` + +JSON to CSV: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/csv-json \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@users.json" \ + -F 'settings={}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/users.json", + "originalSize": 1500, + "processedSize": 2200 +} +``` + +## Notes + +- Conversion direction is auto-detected from the input file extension: `.csv` or `.tsv` produces `.json`, and `.json` produces `.csv`. +- The `pretty` parameter only affects JSON output. When set to `false`, the output is a compact single-line JSON string. +- JSON input must be an array of objects with consistent keys. Each object becomes a row, and each key becomes a column header. +- TSV (tab-separated values) files are supported alongside CSV. diff --git a/apps/docs/tools/duotone.md b/apps/docs/tools/duotone.md new file mode 100644 index 00000000..e499f4b6 --- /dev/null +++ b/apps/docs/tools/duotone.md @@ -0,0 +1,47 @@ +--- +description: Apply a two-color duotone effect with custom shadow and highlight colors. +--- + +# Duotone + +Apply a two-color duotone effect to an image. The image is converted to grayscale, then mapped to a gradient between the shadow color (dark tones) and the highlight color (bright tones). + +## API Endpoint + +`POST /api/v1/tools/duotone` + +Accepts multipart form data with an image file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| shadow | string | No | `"#1e3a8a"` | Shadow hex color (applied to dark tones) | +| highlight | string | No | `"#fbbf24"` | Highlight hex color (applied to bright tones) | +| intensity | integer | No | `100` | Effect intensity (0-100); 0 returns the original, 100 applies the full duotone | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/duotone \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"shadow": "#0f172a", "highlight": "#f97316", "intensity": 80}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", + "originalSize": 2450000, + "processedSize": 1870000 +} +``` + +## Notes + +- Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. +- An `intensity` of less than 100 blends the duotone result with the original image, allowing for subtler effects. +- Popular duotone combinations include navy/gold, teal/coral, and purple/pink. diff --git a/apps/docs/tools/embed-subtitles.md b/apps/docs/tools/embed-subtitles.md new file mode 100644 index 00000000..46a66608 --- /dev/null +++ b/apps/docs/tools/embed-subtitles.md @@ -0,0 +1,46 @@ +--- +description: Mux a subtitle track into the video container. +--- + +# Embed Subtitles + +Mux a subtitle file into the video container as a soft subtitle track that viewers can toggle on or off. + +## API Endpoint + +`POST /api/v1/tools/embed-subtitles` + +Accepts multipart form data with a video file and a subtitle file, plus a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| language | string | No | `"eng"` | ISO 639-2/B language code (3 lowercase letters, e.g. `"eng"`, `"fra"`, `"deu"`) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/embed-subtitles \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F "file=@subtitles.srt" \ + -F 'settings={"language": "fra"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 12520000 +} +``` + +## Notes + +- Upload two files: the first must be a video, the second must be a subtitle file (.srt, .vtt, or .ass). +- Embedded (soft) subtitles can be toggled by the viewer in their media player. For permanently visible subtitles, use the Burn Subtitles tool instead. +- The language code is stored as metadata in the container and helps media players label the subtitle track. diff --git a/apps/docs/tools/epub-convert.md b/apps/docs/tools/epub-convert.md new file mode 100644 index 00000000..c511d818 --- /dev/null +++ b/apps/docs/tools/epub-convert.md @@ -0,0 +1,46 @@ +--- +description: Convert an EPUB to PDF, DOCX, HTML, or Markdown. +--- + +# Convert EPUB + +Convert an EPUB e-book to PDF, Word (DOCX), HTML, or Markdown. Remote resources inside the book are not fetched. + +## API Endpoint + +`POST /api/v1/tools/epub-convert` + +Accepts multipart form data with an EPUB file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| format | string | Yes | - | Output format: `pdf`, `docx`, `html`, `md` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/epub-convert \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@book.epub" \ + -F 'settings={"format": "pdf"}' +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input format: `.epub`. +- Remote resources embedded in the EPUB (external images, fonts) are not fetched for security. +- Image fidelity in the converted output may vary depending on the EPUB structure. +- Conversion is handled by Pandoc on the server. diff --git a/apps/docs/tools/excel-to-pdf.md b/apps/docs/tools/excel-to-pdf.md new file mode 100644 index 00000000..6e13e9e7 --- /dev/null +++ b/apps/docs/tools/excel-to-pdf.md @@ -0,0 +1,43 @@ +--- +description: Convert spreadsheets to PDF. +--- + +# Excel to PDF + +Convert Excel, OpenDocument, or CSV spreadsheets to PDF. Wide sheets may paginate across multiple pages. + +## API Endpoint + +`POST /api/v1/tools/excel-to-pdf` + +Accepts multipart form data with an Excel/ODS/CSV file. + +## Parameters + +This tool has no configurable parameters. Upload a spreadsheet and it will be converted to PDF. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/excel-to-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@budget.xlsx" +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input formats: `.xlsx`, `.xls`, `.ods`, `.csv`. +- Wide sheets may be split across multiple pages in the resulting PDF. +- Charts and conditional formatting are rendered in the PDF output. +- Conversion is handled by LibreOffice running headless on the server. diff --git a/apps/docs/tools/extract-audio.md b/apps/docs/tools/extract-audio.md new file mode 100644 index 00000000..ec2c6a0a --- /dev/null +++ b/apps/docs/tools/extract-audio.md @@ -0,0 +1,45 @@ +--- +description: Pull the audio track out of a video. +--- + +# Extract Audio + +Extract the audio track from a video file and save it as MP3, WAV, or M4A. + +## API Endpoint + +`POST /api/v1/tools/extract-audio` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| format | string | No | `"mp3"` | Output audio format: `mp3`, `wav`, `m4a` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/extract-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"format": "mp3"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp3", + "originalSize": 12500000, + "processedSize": 3200000 +} +``` + +## Notes + +- If the video has no audio track, the request returns a 400 error. +- MP3 is lossy but widely compatible. WAV is lossless but large. M4A (AAC) offers a good balance of quality and size. +- When the source audio is already AAC and the output format is M4A, the audio stream is copied without re-encoding. diff --git a/apps/docs/tools/extract-pages.md b/apps/docs/tools/extract-pages.md new file mode 100644 index 00000000..2f5a3ea0 --- /dev/null +++ b/apps/docs/tools/extract-pages.md @@ -0,0 +1,44 @@ +--- +description: Pull selected pages from a PDF into a new document. +--- + +# Extract Pages + +Pull selected pages from a PDF into a new, smaller document. + +## API Endpoint + +`POST /api/v1/tools/extract-pages` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| range | string | Yes | - | Page range in qpdf syntax, e.g. `"1-5,8,10-z"` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/extract-pages \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"range": "1-5,8,10-z"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 3200000, + "processedSize": 1100000 +} +``` + +## Notes + +- Page ranges use qpdf syntax: `1-5` for pages 1 through 5, `z` for the last page, and commas to combine ranges (e.g. `1-3,7,10-z`). +- The extracted pages retain their original formatting, annotations, and links. diff --git a/apps/docs/tools/extract-subtitles.md b/apps/docs/tools/extract-subtitles.md new file mode 100644 index 00000000..5ee8df1c --- /dev/null +++ b/apps/docs/tools/extract-subtitles.md @@ -0,0 +1,42 @@ +--- +description: Pull the subtitle track out of a video as an SRT file. +--- + +# Extract Subtitles + +Extract the embedded subtitle track from a video container and download it as an SRT file. + +## API Endpoint + +`POST /api/v1/tools/extract-subtitles` + +Accepts multipart form data with a video file. This tool has no configurable settings. + +## Parameters + +This tool has no parameters. It extracts the first subtitle track found in the video container. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/extract-subtitles \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.srt", + "originalSize": 12500000, + "processedSize": 4500 +} +``` + +## Notes + +- The video must contain an embedded subtitle track. If no subtitle track is found, the request returns a 400 error. +- If the video has multiple subtitle tracks, the first one is extracted. +- The output format is SRT regardless of the original subtitle format in the container. diff --git a/apps/docs/tools/extract-zip.md b/apps/docs/tools/extract-zip.md new file mode 100644 index 00000000..dce284a0 --- /dev/null +++ b/apps/docs/tools/extract-zip.md @@ -0,0 +1,43 @@ +--- +description: Safely extract files from a ZIP archive with bomb protection. +--- + +# Extract ZIP + +Safely extract files from a ZIP archive. Single-file archives return the contained file directly; multi-file archives return a flat ZIP with the extracted contents. + +## API Endpoint + +`POST /api/v1/tools/extract-zip` + +Accepts multipart form data with a ZIP file. No settings field is required. + +## Parameters + +This tool has no configurable parameters. Upload a `.zip` file to extract. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/extract-zip \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@archive.zip" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/archive.zip", + "originalSize": 2800000, + "processedSize": 3500000 +} +``` + +## Notes + +- Only `.zip` files are accepted as input. +- If the archive contains a single file, that file is returned directly (not wrapped in a ZIP). +- If the archive contains multiple files, a flat ZIP is returned with all files extracted to the root level (nested directory structure is flattened). +- Built-in bomb protection rejects archives with excessive compression ratios or file counts to prevent resource exhaustion. diff --git a/apps/docs/tools/fade-audio.md b/apps/docs/tools/fade-audio.md new file mode 100644 index 00000000..d6362a9a --- /dev/null +++ b/apps/docs/tools/fade-audio.md @@ -0,0 +1,46 @@ +--- +description: Add fade-in and fade-out effects to audio. +--- + +# Fade Audio + +Add fade-in and fade-out effects to the beginning and end of an audio file. + +## API Endpoint + +`POST /api/v1/tools/fade-audio` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| fadeInS | number | No | `1` | Fade-in duration in seconds (0 to 30) | +| fadeOutS | number | No | `1` | Fade-out duration in seconds (0 to 30) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/fade-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"fadeInS": 2, "fadeOutS": 3}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 4500000 +} +``` + +## Notes + +- Set either value to `0` to skip that fade direction. +- The fade duration should not exceed the audio length. +- Output format matches the input format. diff --git a/apps/docs/tools/flatten-pdf.md b/apps/docs/tools/flatten-pdf.md new file mode 100644 index 00000000..99fe7754 --- /dev/null +++ b/apps/docs/tools/flatten-pdf.md @@ -0,0 +1,43 @@ +--- +description: Bake forms and annotations into page content. +--- + +# Flatten PDF + +Bake interactive form fields and annotations into the page content, producing a static PDF that looks the same everywhere. + +## API Endpoint + +`POST /api/v1/tools/flatten-pdf` + +Accepts multipart form data with a PDF file. + +## Parameters + +This tool has no configurable parameters. Upload a PDF and all forms and annotations will be flattened. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/flatten-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@form.pdf" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/form.pdf", + "originalSize": 185000, + "processedSize": 172000 +} +``` + +## Notes + +- Accepted input format: `.pdf`. +- This is a fast (synchronous) tool that returns the result directly. +- Form field values are preserved as static text in the output. +- Annotations (comments, highlights, sticky notes) become part of the page content and can no longer be edited. diff --git a/apps/docs/tools/gif-to-video.md b/apps/docs/tools/gif-to-video.md new file mode 100644 index 00000000..38e16a5f --- /dev/null +++ b/apps/docs/tools/gif-to-video.md @@ -0,0 +1,45 @@ +--- +description: Convert an animated GIF into an MP4 or WebM video. +--- + +# GIF to Video + +Convert an animated GIF into a compact MP4 or WebM video file. + +## API Endpoint + +`POST /api/v1/tools/gif-to-video` + +Accepts multipart form data with a GIF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| format | string | No | `"mp4"` | Output format: `mp4`, `webm` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/gif-to-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@animation.gif" \ + -F 'settings={"format": "mp4"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.mp4", + "originalSize": 8500000, + "processedSize": 950000 +} +``` + +## Notes + +- Converting GIF to video typically reduces file size by 80-90% while maintaining the same visual quality. +- Only animated GIF files are accepted. Static images should use the image Convert tool. +- MP4 uses H.264 encoding, WebM uses VP9. diff --git a/apps/docs/tools/gif-webp.md b/apps/docs/tools/gif-webp.md new file mode 100644 index 00000000..1cec40e6 --- /dev/null +++ b/apps/docs/tools/gif-webp.md @@ -0,0 +1,48 @@ +--- +description: Convert animated GIF to WebP and vice versa, preserving all frames. +--- + +# GIF/WebP Converter + +Convert animated GIF files to WebP and vice versa, preserving all frames and animation timing. WebP animations are typically 25-35% smaller than equivalent GIFs. + +## API Endpoint + +`POST /api/v1/tools/gif-webp` + +Accepts multipart form data with a GIF or WebP file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| quality | integer | No | `80` | Output quality for WebP encoding (1-100) | +| lossless | boolean | No | `false` | Use lossless WebP compression | +| resizePercent | integer | No | `100` | Scale the output by percentage (10-100) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/gif-webp \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@animation.gif" \ + -F 'settings={"quality": 85, "resizePercent": 50}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/animation.webp", + "originalSize": 3500000, + "processedSize": 2200000 +} +``` + +## Notes + +- Only `.gif` and `.webp` files are accepted. Other image formats are not supported by this tool. +- The conversion direction is automatic: GIF input produces WebP output, and WebP input produces GIF output. +- The `quality` and `lossless` options only apply when encoding to WebP. When converting to GIF, the output uses the standard GIF palette. +- Use `resizePercent` to reduce the dimensions (and file size) of large animations. diff --git a/apps/docs/tools/grayscale-pdf.md b/apps/docs/tools/grayscale-pdf.md new file mode 100644 index 00000000..2a1dce5e --- /dev/null +++ b/apps/docs/tools/grayscale-pdf.md @@ -0,0 +1,41 @@ +--- +description: Convert all colors in a PDF to grayscale. +--- + +# Grayscale PDF + +Convert all colors in a PDF to grayscale, producing a black-and-white version of the document. + +## API Endpoint + +`POST /api/v1/tools/grayscale-pdf` + +Accepts multipart form data with a PDF file. No `settings` field is required. + +## Parameters + +This tool has no settings parameters. Upload the PDF file directly. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/grayscale-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 3200000, + "processedSize": 2800000 +} +``` + +## Notes + +- All color spaces (RGB, CMYK) are converted to grayscale, including embedded images, vector graphics, and text. +- The output file is often smaller than the original because grayscale data requires fewer bytes per pixel. diff --git a/apps/docs/tools/histogram.md b/apps/docs/tools/histogram.md new file mode 100644 index 00000000..6d3423fc --- /dev/null +++ b/apps/docs/tools/histogram.md @@ -0,0 +1,62 @@ +--- +description: Generate an RGB histogram chart with per-channel statistics from an image. +--- + +# Histogram + +Generate an RGB histogram chart from an image. Returns a PNG histogram image along with per-channel statistics and raw 256-bin histogram data in the response JSON. + +## API Endpoint + +`POST /api/v1/tools/histogram` + +Accepts multipart form data with an image file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| scale | string | No | `"linear"` | Y-axis scale: `linear` or `log` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/histogram \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"scale": "linear"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/histogram.png", + "originalSize": 2450000, + "processedSize": 12000, + "bins": { + "r": [0, 12, 45, "... (256 values)"], + "g": [0, 8, 38, "... (256 values)"], + "b": [2, 15, 52, "... (256 values)"], + "lum": [0, 10, 40, "... (256 values)"] + }, + "stats": { + "r": { "mean": 128, "median": 132, "stdev": 48.5 }, + "g": { "mean": 119, "median": 121, "stdev": 44.2 }, + "b": { "mean": 105, "median": 108, "stdev": 51.3 }, + "lum": { "mean": 118, "median": 120, "stdev": 45.1 } + }, + "mean": { "r": 128, "g": 119, "b": 105 }, + "max": { "r": 4200, "g": 3800, "b": 4100 } +} +``` + +## Notes + +- The `downloadUrl` points to a rendered PNG histogram chart showing the R, G, B, and luminance distributions. +- `bins` contains raw 256-value arrays for each channel (red, green, blue, luminance), suitable for rendering custom visualizations. +- `stats` provides mean, median, and standard deviation per channel. +- `mean` and `max` are backward-compatible shorthand fields. +- Use `log` scale when the histogram is dominated by a few peaks and you want to see detail in the lower bins. +- HEIC, RAW, PSD, and SVG inputs are automatically decoded before analysis. diff --git a/apps/docs/tools/html-to-pdf.md b/apps/docs/tools/html-to-pdf.md new file mode 100644 index 00000000..46884dfb --- /dev/null +++ b/apps/docs/tools/html-to-pdf.md @@ -0,0 +1,43 @@ +--- +description: Convert an HTML file to PDF. +--- + +# HTML to PDF + +Convert an HTML file to a styled PDF document. Remote resources (external images, stylesheets, scripts) are disabled for privacy. + +## API Endpoint + +`POST /api/v1/tools/html-to-pdf` + +Accepts multipart form data with an HTML file. + +## Parameters + +This tool has no configurable parameters. Upload an HTML file and it will be converted to PDF. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/html-to-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@page.html" +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input formats: `.html`, `.htm`. +- Remote resources (images, stylesheets, scripts referenced via URLs) are not fetched for privacy and security. +- Inline styles and embedded images (data URIs) are preserved. +- Conversion is handled by WeasyPrint on the server. diff --git a/apps/docs/tools/image-pad.md b/apps/docs/tools/image-pad.md new file mode 100644 index 00000000..d1ba8225 --- /dev/null +++ b/apps/docs/tools/image-pad.md @@ -0,0 +1,51 @@ +--- +description: Pad an image to a target aspect ratio with a solid color, transparent, or blurred background. +--- + +# Image Pad + +Pad an image to a target aspect ratio by adding a solid color, transparent, or blurred background around it. Useful for fitting images into fixed aspect ratios for social media or print without cropping. + +## API Endpoint + +`POST /api/v1/tools/image-pad` + +Accepts multipart form data with an image file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| target | string | No | `"1:1"` | Target aspect ratio: `16:9`, `9:16`, `1:1`, `4:3`, `3:4`, or `custom` | +| ratioW | integer | No | `1` | Custom ratio width (1-100, used when target is `custom`) | +| ratioH | integer | No | `1` | Custom ratio height (1-100, used when target is `custom`) | +| background | string | No | `"color"` | Background mode: `color`, `transparent`, or `blur` | +| color | string | No | `"#ffffff"` | Background hex color (when background is `color`) | +| padding | integer | No | `0` | Extra padding as percentage of canvas (0-50) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/image-pad \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"target": "16:9", "background": "blur", "padding": 5}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", + "originalSize": 2450000, + "processedSize": 3100000 +} +``` + +## Notes + +- The `blur` background mode creates a blurred copy of the original image as the pad fill, producing a visually cohesive result. +- When using `transparent` background, the output is converted to PNG to preserve alpha. +- Output format matches the input format unless transparency is involved. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. +- Set `target` to `custom` and provide `ratioW` and `ratioH` for arbitrary aspect ratios (e.g., `ratioW: 3, ratioH: 2` for 3:2). diff --git a/apps/docs/tools/images-to-video.md b/apps/docs/tools/images-to-video.md new file mode 100644 index 00000000..d0394e3c --- /dev/null +++ b/apps/docs/tools/images-to-video.md @@ -0,0 +1,51 @@ +--- +description: Turn a set of images into a slideshow video. +--- + +# Images to Video + +Turn a set of images into a slideshow video with configurable duration per image, resolution, and frame rate. + +## API Endpoint + +`POST /api/v1/tools/images-to-video` + +Accepts multipart form data with two or more image files and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| secondsPerImage | number | No | `2` | Display duration per image in seconds (0.5-10) | +| resolution | string | No | `"720p"` | Output resolution: `1080p`, `720p`, `square` | +| fps | integer | No | `30` | Output frame rate (10-60) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/images-to-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@slide1.jpg" \ + -F "file=@slide2.jpg" \ + -F "file=@slide3.jpg" \ + -F "file=@slide4.jpg" \ + -F 'settings={"secondsPerImage": 3, "resolution": "1080p"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/slideshow.mp4", + "originalSize": 3500000, + "processedSize": 1200000 +} +``` + +## Notes + +- Accepts 2-60 image files per request. Images appear in the video in upload order. +- Images are resized and padded to fit the target resolution while preserving aspect ratio. +- The `square` resolution option produces a 720x720 video, useful for social media. +- Output format is always MP4 (H.264). diff --git a/apps/docs/tools/json-xml.md b/apps/docs/tools/json-xml.md new file mode 100644 index 00000000..91e9f038 --- /dev/null +++ b/apps/docs/tools/json-xml.md @@ -0,0 +1,56 @@ +--- +description: Convert between JSON and XML, both directions. +--- + +# JSON to XML + +Convert between JSON and XML formats in both directions. Upload a JSON file to get XML, or upload an XML file to get JSON. + +## API Endpoint + +`POST /api/v1/tools/json-xml` + +Accepts multipart form data with a JSON or XML file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| pretty | boolean | No | `true` | Pretty-print output with indentation | + +## Example Request + +JSON to XML: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/json-xml \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@config.json" \ + -F 'settings={"pretty": true}' +``` + +XML to JSON: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/json-xml \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@config.xml" \ + -F 'settings={"pretty": true}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config.xml", + "originalSize": 850, + "processedSize": 1200 +} +``` + +## Notes + +- Conversion direction is auto-detected from the input file extension: `.json` produces `.xml`, and `.xml` produces `.json`. +- The `pretty` parameter applies to both directions. When `false`, the output is compact with no indentation. +- XML attributes and nested structures are preserved during round-trip conversion where possible. diff --git a/apps/docs/tools/linearize-pdf.md b/apps/docs/tools/linearize-pdf.md new file mode 100644 index 00000000..f32a5d64 --- /dev/null +++ b/apps/docs/tools/linearize-pdf.md @@ -0,0 +1,42 @@ +--- +description: Linearize a PDF for fast web viewing (progressive download). +--- + +# Web-Optimize PDF + +Linearize a PDF so it can be progressively downloaded and displayed in web browsers without waiting for the full file. + +## API Endpoint + +`POST /api/v1/tools/linearize-pdf` + +Accepts multipart form data with a PDF file. No `settings` field is required. + +## Parameters + +This tool has no settings parameters. Upload the PDF file directly. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/linearize-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2460000 +} +``` + +## Notes + +- Linearization rearranges the PDF's internal structure so the first page can render before the full file has downloaded. +- The output file may be slightly larger than the input due to the added linearization data. +- Already-linearized PDFs are re-linearized without issue. diff --git a/apps/docs/tools/lqip-placeholder.md b/apps/docs/tools/lqip-placeholder.md new file mode 100644 index 00000000..ec291fb5 --- /dev/null +++ b/apps/docs/tools/lqip-placeholder.md @@ -0,0 +1,59 @@ +--- +description: Generate a tiny low-quality image placeholder with base64 data URI. +--- + +# LQIP Placeholder + +Generate a tiny low-quality image placeholder (LQIP) from a source image. Returns a small placeholder file along with a base64 data URI, ready-to-use HTML `` tag, and CSS `background-image` snippet for immediate embedding. + +## API Endpoint + +`POST /api/v1/tools/lqip-placeholder` + +Accepts multipart form data with an image file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| width | integer | No | `16` | Target width in pixels (4-64) | +| blur | number | No | `2` | Blur radius for the blur strategy (0-20) | +| strategy | string | No | `"blur"` | Placeholder strategy: `blur`, `pixelate`, or `solid` | +| format | string | No | `"webp"` | Output format: `webp`, `png`, or `jpeg` | +| quality | integer | No | `50` | Output quality (1-100) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/lqip-placeholder \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"width": 20, "strategy": "blur", "format": "webp"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.webp", + "originalSize": 2450000, + "processedSize": 280, + "dataUri": "data:image/webp;base64,UklGR...", + "width": 20, + "height": 13, + "bytes": 280, + "strategy": "blur", + "html": "\"\"", + "css": "background-image: url(data:image/webp;base64,UklGR...);" +} +``` + +## Notes + +- The `dataUri` field contains the complete data URI, ready for use in `src` attributes or CSS without any additional requests. +- The `html` and `css` fields provide copy-paste snippets for common use cases. +- The `blur` strategy produces a soft, blurred thumbnail. The `pixelate` strategy creates a blocky mosaic. The `solid` strategy returns a single averaged color. +- Typical placeholder sizes are 200-500 bytes, making them suitable for inlining directly in HTML. +- Height is calculated automatically to preserve the source image's aspect ratio. +- HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. diff --git a/apps/docs/tools/markdown-to-docx.md b/apps/docs/tools/markdown-to-docx.md new file mode 100644 index 00000000..a1d95b48 --- /dev/null +++ b/apps/docs/tools/markdown-to-docx.md @@ -0,0 +1,43 @@ +--- +description: Convert a Markdown file to a Word document (DOCX). +--- + +# Markdown to Word + +Convert a Markdown file to a Word document (DOCX), preserving headings, lists, code blocks, and other formatting. + +## API Endpoint + +`POST /api/v1/tools/markdown-to-docx` + +Accepts multipart form data with a Markdown file. + +## Parameters + +This tool has no configurable parameters. Upload a Markdown file and it will be converted to DOCX. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/markdown-to-docx \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@README.md" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/README.docx", + "originalSize": 4500, + "processedSize": 18200 +} +``` + +## Notes + +- Accepted input formats: `.md`, `.markdown`. +- This is a fast (synchronous) tool that returns the result directly. +- Headings, bold, italic, links, code blocks, and lists are mapped to Word styles. +- Conversion is handled by Pandoc on the server. diff --git a/apps/docs/tools/markdown-to-html.md b/apps/docs/tools/markdown-to-html.md new file mode 100644 index 00000000..25a5d3ee --- /dev/null +++ b/apps/docs/tools/markdown-to-html.md @@ -0,0 +1,43 @@ +--- +description: Convert a Markdown file to a standalone HTML page. +--- + +# Markdown to HTML + +Convert a Markdown file to a standalone HTML page. Remote images referenced in the source are left as-is in the output. + +## API Endpoint + +`POST /api/v1/tools/markdown-to-html` + +Accepts multipart form data with a Markdown file. + +## Parameters + +This tool has no configurable parameters. Upload a Markdown file and it will be converted to HTML. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/markdown-to-html \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@notes.md" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/notes.html", + "originalSize": 3200, + "processedSize": 5800 +} +``` + +## Notes + +- Accepted input formats: `.md`, `.markdown`. +- This is a fast (synchronous) tool that returns the result directly. +- The output is a self-contained HTML page with inline styles. +- Remote image URLs in the Markdown source are preserved as-is and not fetched. diff --git a/apps/docs/tools/markdown-to-pdf.md b/apps/docs/tools/markdown-to-pdf.md new file mode 100644 index 00000000..3e6d78f8 --- /dev/null +++ b/apps/docs/tools/markdown-to-pdf.md @@ -0,0 +1,43 @@ +--- +description: Convert a Markdown file to a styled PDF. +--- + +# Markdown to PDF + +Convert a Markdown file to a styled PDF document. Remote resources are disabled for privacy. + +## API Endpoint + +`POST /api/v1/tools/markdown-to-pdf` + +Accepts multipart form data with a Markdown file. + +## Parameters + +This tool has no configurable parameters. Upload a Markdown file and it will be converted to PDF. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/markdown-to-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.md" +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input formats: `.md`, `.markdown`. +- Remote resources (images, stylesheets referenced via URLs) are not fetched for privacy and security. +- The Markdown is first rendered to HTML, then converted to PDF via WeasyPrint. +- Code blocks, tables, and other Markdown elements are styled in the PDF output. diff --git a/apps/docs/tools/merge-audio.md b/apps/docs/tools/merge-audio.md new file mode 100644 index 00000000..b9af04db --- /dev/null +++ b/apps/docs/tools/merge-audio.md @@ -0,0 +1,48 @@ +--- +description: Combine multiple audio files into one sequential track. +--- + +# Merge Audio + +Combine two or more audio files into a single sequential track, concatenated in the order they are uploaded. + +## API Endpoint + +`POST /api/v1/tools/merge-audio` + +Accepts multipart form data with multiple audio files and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| format | string | No | `"mp3"` | Output format: `mp3`, `wav`, `flac`, `m4a` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/merge-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@intro.mp3" \ + -F "file=@main.mp3" \ + -F "file=@outro.mp3" \ + -F 'settings={"format": "mp3"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.mp3", + "originalSize": 9500000, + "processedSize": 9200000 +} +``` + +## Notes + +- Accepts 2 to 10 audio files per request. +- Files are concatenated in upload order. +- All input files are re-encoded to the chosen output format and sample rate for seamless joining. +- Mixed input formats are supported (e.g. one WAV and one MP3). diff --git a/apps/docs/tools/merge-csvs.md b/apps/docs/tools/merge-csvs.md new file mode 100644 index 00000000..a804a758 --- /dev/null +++ b/apps/docs/tools/merge-csvs.md @@ -0,0 +1,45 @@ +--- +description: Combine multiple CSV or TSV files with matching columns into one. +--- + +# Merge CSVs + +Combine multiple CSV or TSV files with matching columns into a single merged file. All input files must have the same column headers. + +## API Endpoint + +`POST /api/v1/tools/merge-csvs` + +Accepts multipart form data with two or more CSV files. No settings field is required. + +## Parameters + +This tool has no configurable parameters. Upload 2--20 CSV or TSV files with matching column headers. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/merge-csvs \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@january.csv" \ + -F "file=@february.csv" \ + -F "file=@march.csv" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.csv", + "originalSize": 30000, + "processedSize": 28500 +} +``` + +## Notes + +- Requires between 2 and 20 input files. +- All files must share the same column headers. The merge will fail if columns do not match. +- The header row is included once in the output; data rows from all files are concatenated in upload order. +- Both CSV and TSV files are accepted, but all files in a single request should use the same delimiter. diff --git a/apps/docs/tools/merge-pdf.md b/apps/docs/tools/merge-pdf.md new file mode 100644 index 00000000..7db593c1 --- /dev/null +++ b/apps/docs/tools/merge-pdf.md @@ -0,0 +1,50 @@ +--- +description: Combine multiple PDFs into a single document. +--- + +# Merge PDFs + +Combine two or more PDF files into a single document, preserving the page order of each input file. + +## API Endpoint + +`POST /api/v1/tools/merge-pdf` + +Accepts multipart form data with two or more PDF files. No `settings` field is required. + +## Parameters + +This tool has no settings parameters. Simply upload two or more PDF files. + +| Constraint | Value | +|------------|-------| +| Minimum files | 2 | +| Maximum files | 20 | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/merge-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document1.pdf" \ + -F "file=@document2.pdf" \ + -F "file=@document3.pdf" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/merged.pdf", + "originalSize": 4500000, + "processedSize": 4200000 +} +``` + +## Notes + +- Files are merged in the order they are uploaded. +- At least two PDF files are required; the request will fail with a 400 error if fewer are provided. +- The maximum number of input files is 20. +- Encrypted PDFs must be unlocked before merging. diff --git a/apps/docs/tools/merge-videos.md b/apps/docs/tools/merge-videos.md new file mode 100644 index 00000000..7d6cdaeb --- /dev/null +++ b/apps/docs/tools/merge-videos.md @@ -0,0 +1,43 @@ +--- +description: Join multiple video clips into one file. +--- + +# Merge Videos + +Join multiple video clips into a single MP4 file. All inputs are normalized to the first video's resolution and 30 fps. + +## API Endpoint + +`POST /api/v1/tools/merge-videos` + +Accepts multipart form data with two or more video files. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. + +## Parameters + +This tool has no settings parameters. Upload 2-10 video files as multiple `file` parts. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/merge-videos \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@intro.mp4" \ + -F "file=@main.mp4" \ + -F "file=@outro.mp4" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Clips are concatenated in the order they are uploaded. +- All clips are re-encoded to match the first clip's resolution, frame rate (30 fps), and codec (H.264). Mismatched inputs are automatically normalized. +- Accepts 2-10 video files per request. +- Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. diff --git a/apps/docs/tools/mute-video.md b/apps/docs/tools/mute-video.md new file mode 100644 index 00000000..d84c59b7 --- /dev/null +++ b/apps/docs/tools/mute-video.md @@ -0,0 +1,41 @@ +--- +description: Remove the audio track from a video. +--- + +# Mute Video + +Remove the audio track from a video, leaving only the visual stream. + +## API Endpoint + +`POST /api/v1/tools/mute-video` + +Accepts multipart form data with a video file. This tool has no configurable settings. + +## Parameters + +This tool has no parameters. It strips the audio track from the uploaded video. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/mute-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 8900000 +} +``` + +## Notes + +- The video stream is copied without re-encoding, so there is no quality loss. +- If the input video has no audio track, the file is returned unchanged. diff --git a/apps/docs/tools/noise-reduction.md b/apps/docs/tools/noise-reduction.md new file mode 100644 index 00000000..b766353b --- /dev/null +++ b/apps/docs/tools/noise-reduction.md @@ -0,0 +1,45 @@ +--- +description: Reduce background noise from audio with FFT-based denoising. +--- + +# Noise Reduction + +Reduce background noise in an audio file using FFT-based denoising with selectable strength. + +## API Endpoint + +`POST /api/v1/tools/noise-reduction` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| strength | string | No | `"medium"` | Denoising strength: `light`, `medium`, `strong` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/noise-reduction \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"strength": "strong"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 4500000 +} +``` + +## Notes + +- `light` preserves more detail but removes less noise. `strong` removes more noise but may introduce subtle artifacts. +- Best results on recordings with consistent background noise (fan hum, air conditioning, static). +- Output format matches the input format. diff --git a/apps/docs/tools/normalize-audio.md b/apps/docs/tools/normalize-audio.md new file mode 100644 index 00000000..fb57610b --- /dev/null +++ b/apps/docs/tools/normalize-audio.md @@ -0,0 +1,43 @@ +--- +description: Even out loudness to broadcast standard levels (EBU R128). +--- + +# Normalize Audio + +Even out audio loudness to broadcast standard levels using EBU R128 normalization (-16 LUFS). + +## API Endpoint + +`POST /api/v1/tools/normalize-audio` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +This tool has no configurable parameters. It applies EBU R128 loudness normalization automatically. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/normalize-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 4500000 +} +``` + +## Notes + +- Uses the EBU R128 loudness standard, targeting -16 LUFS. +- Ideal for podcasts, audiobooks, and broadcast content where consistent loudness is important. +- The source sample rate is preserved in the output. +- Output format matches the input format. diff --git a/apps/docs/tools/nup-pdf.md b/apps/docs/tools/nup-pdf.md new file mode 100644 index 00000000..1bc0e757 --- /dev/null +++ b/apps/docs/tools/nup-pdf.md @@ -0,0 +1,45 @@ +--- +description: Arrange multiple PDF pages per sheet (2-up, 4-up, etc.). +--- + +# N-up PDF + +Arrange multiple pages per sheet to save paper when printing, such as 2-up or 4-up layouts. + +## API Endpoint + +`POST /api/v1/tools/nup-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| perSheet | integer | No | `2` | Pages per sheet: `2`, `3`, `4`, `8`, `9`, `12`, or `16` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/nup-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"perSheet": 4}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2300000 +} +``` + +## Notes + +- Pages are arranged in reading order (left to right, top to bottom). +- The output page size matches the original; individual pages are scaled down to fit the grid. +- A 20-page document with `perSheet: 4` produces a 5-page output. diff --git a/apps/docs/tools/ocr-pdf.md b/apps/docs/tools/ocr-pdf.md new file mode 100644 index 00000000..89dd7ceb --- /dev/null +++ b/apps/docs/tools/ocr-pdf.md @@ -0,0 +1,50 @@ +--- +description: Extract text from PDF documents using AI-powered OCR. +--- + +# PDF OCR + +Extract text from PDF documents using AI-powered optical character recognition. Supports multiple quality tiers and languages. Requires the OCR feature bundle to be installed. + +## API Endpoint + +`POST /api/v1/tools/ocr-pdf` + +Accepts multipart form data with a PDF file and an optional JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| quality | string | No | `"balanced"` | OCR quality tier: `fast`, `balanced`, `best` | +| language | string | No | `"auto"` | Document language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` | +| pages | string | No | `"all"` | Page selection, e.g. `"all"`, `"1-3"`, `"1,3,5"` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/ocr-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@scanned.pdf" \ + -F 'settings={"quality": "best", "language": "en", "pages": "1-5"}' +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input format: `.pdf`. +- This is an AI tool that requires the **OCR feature bundle** to be installed. If the bundle is not installed, the API returns `501 Not Implemented`. +- The `fast` quality tier uses a lighter model for quicker processing; `best` uses a more accurate model at the cost of speed. +- The `auto` language setting attempts to detect the document language automatically. +- You can target specific pages using ranges (`"1-3"`), comma-separated lists (`"1,3,5"`), or `"all"` for every page. +- For PDFs that already contain selectable text, consider using the faster [PDF to Text](./pdf-to-text) tool instead. diff --git a/apps/docs/tools/organize-pdf.md b/apps/docs/tools/organize-pdf.md new file mode 100644 index 00000000..e635811b --- /dev/null +++ b/apps/docs/tools/organize-pdf.md @@ -0,0 +1,45 @@ +--- +description: Reorder pages in a PDF with an explicit page order. +--- + +# Organize PDF + +Reorder pages in a PDF by specifying the desired page sequence. + +## API Endpoint + +`POST /api/v1/tools/organize-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| order | string | Yes | - | Desired page order in qpdf syntax, e.g. `"3,1,2,5-z"` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/organize-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"order": "3,1,2,5-z"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2450000 +} +``` + +## Notes + +- Page ranges use qpdf syntax: `3,1,2` reorders the first three pages, and `5-z` appends pages 5 through the last page. +- Pages can be duplicated by listing them more than once (e.g. `"1,1,2,3"` duplicates page 1). +- Pages not listed in the order string are omitted from the output. diff --git a/apps/docs/tools/pdf-metadata.md b/apps/docs/tools/pdf-metadata.md new file mode 100644 index 00000000..037f10d6 --- /dev/null +++ b/apps/docs/tools/pdf-metadata.md @@ -0,0 +1,58 @@ +--- +description: Read and write PDF document metadata. +--- + +# PDF Metadata + +Read and update PDF document metadata fields such as title, author, subject, and keywords. When no settings are provided, the existing metadata is returned without modification. + +## API Endpoint + +`POST /api/v1/tools/pdf-metadata` + +Accepts multipart form data with a PDF file and an optional JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| title | string | No | - | Document title (max 500 characters) | +| author | string | No | - | Document author (max 500 characters) | +| subject | string | No | - | Document subject (max 500 characters) | +| keywords | string | No | - | Document keywords (max 500 characters) | + +All parameters are optional. Omitted fields are left unchanged. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/pdf-metadata \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@report.pdf" \ + -F 'settings={"title": "Q2 Report", "author": "Finance Team"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/report.pdf", + "originalSize": 245000, + "processedSize": 245200, + "metadata": { + "title": "Q2 Report", + "author": "Finance Team", + "subject": "", + "keywords": "" + } +} +``` + +## Notes + +- Accepted input format: `.pdf`. +- This is a fast (synchronous) tool that returns the result directly. +- The `metadata` field in the response contains the resulting metadata after any updates. +- To read metadata without modifying it, omit the `settings` field or send an empty object. +- Each metadata field is limited to 500 characters. diff --git a/apps/docs/tools/pdf-page-numbers.md b/apps/docs/tools/pdf-page-numbers.md new file mode 100644 index 00000000..0a710805 --- /dev/null +++ b/apps/docs/tools/pdf-page-numbers.md @@ -0,0 +1,51 @@ +--- +description: Add page numbers to every page of a PDF. +--- + +# PDF Page Numbers + +Add "Page N of M" page numbers to every page of a PDF. + +## API Endpoint + +`POST /api/v1/tools/pdf-page-numbers` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| position | string | No | `"bc"` | Page number placement: `bl`, `bc`, `br`, `tl`, `tc`, `tr` | +| fontSize | integer | No | `10` | Font size in points (6-24) | + +### Position Values + +- `tl` top-left, `tc` top-center, `tr` top-right +- `bl` bottom-left, `bc` bottom-center, `br` bottom-right + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/pdf-page-numbers \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"position": "bc", "fontSize": 12}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2470000 +} +``` + +## Notes + +- Page numbers are rendered in the format "Page 1 of 10". +- Numbers are added to every page, including any existing title or cover pages. +- The default position `"bc"` places numbers at the bottom center of each page. diff --git a/apps/docs/tools/pdf-to-text.md b/apps/docs/tools/pdf-to-text.md new file mode 100644 index 00000000..39b1d25d --- /dev/null +++ b/apps/docs/tools/pdf-to-text.md @@ -0,0 +1,44 @@ +--- +description: Extract plain text from a PDF. +--- + +# PDF to Text + +Extract all readable plain text from a PDF document into a text file. + +## API Endpoint + +`POST /api/v1/tools/pdf-to-text` + +Accepts multipart form data with a PDF file. + +## Parameters + +This tool has no configurable parameters. Upload a PDF and its text content will be extracted. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/pdf-to-text \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@report.pdf" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/report.txt", + "originalSize": 520000, + "processedSize": 14300, + "chars": 14300 +} +``` + +## Notes + +- Accepted input format: `.pdf`. +- This is a fast (synchronous) tool that returns the result directly. +- The `chars` field in the response indicates the number of characters extracted. +- Only digitally embedded text is extracted. For scanned documents or image-based PDFs, use the [PDF OCR](./ocr-pdf) tool instead. diff --git a/apps/docs/tools/pdf-to-word.md b/apps/docs/tools/pdf-to-word.md new file mode 100644 index 00000000..574f7312 --- /dev/null +++ b/apps/docs/tools/pdf-to-word.md @@ -0,0 +1,43 @@ +--- +description: Convert a PDF to a Word document (DOCX). +--- + +# PDF to Word + +Convert a text-based PDF to a Word document (DOCX). Best suited for PDFs with selectable text; scanned pages will need OCR first. + +## API Endpoint + +`POST /api/v1/tools/pdf-to-word` + +Accepts multipart form data with a PDF file. + +## Parameters + +This tool has no configurable parameters. Upload a PDF and it will be converted to DOCX. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/pdf-to-word \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@report.pdf" +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input format: `.pdf`. +- Works best with text-based PDFs. Scanned or image-only pages will produce empty or minimal output; use [PDF OCR](./ocr-pdf) to add a text layer first. +- Conversion is handled by LibreOffice running headless on the server. +- Complex layouts (multi-column, overlapping elements) may not convert perfectly. diff --git a/apps/docs/tools/pdfa-convert.md b/apps/docs/tools/pdfa-convert.md new file mode 100644 index 00000000..8c4201a8 --- /dev/null +++ b/apps/docs/tools/pdfa-convert.md @@ -0,0 +1,42 @@ +--- +description: Convert a PDF to archival PDF/A-2 format for long-term preservation. +--- + +# PDF/A Convert + +Convert a PDF to the PDF/A-2 archival format, suitable for long-term preservation and regulatory compliance. + +## API Endpoint + +`POST /api/v1/tools/pdfa-convert` + +Accepts multipart form data with a PDF file. No `settings` field is required. + +## Parameters + +This tool has no settings parameters. Upload the PDF file directly. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/pdfa-convert \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2600000 +} +``` + +## Notes + +- The output conforms to the PDF/A-2 standard. +- PDF/A embeds all fonts and disallows external references, so the output file may be larger than the original. +- Encryption and JavaScript are stripped during conversion, as they are not permitted by the PDF/A standard. diff --git a/apps/docs/tools/pitch-shift.md b/apps/docs/tools/pitch-shift.md new file mode 100644 index 00000000..47e99098 --- /dev/null +++ b/apps/docs/tools/pitch-shift.md @@ -0,0 +1,46 @@ +--- +description: Raise or lower audio pitch by semitones without changing speed. +--- + +# Pitch Shift + +Raise or lower the pitch of an audio file by a number of semitones without changing its playback speed. + +## API Endpoint + +`POST /api/v1/tools/pitch-shift` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| semitones | integer | No | `3` | Semitones to shift (-12 to 12). Must be nonzero. | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/pitch-shift \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"semitones": -5}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 4500000 +} +``` + +## Notes + +- Positive values raise the pitch; negative values lower it. +- A shift of 12 semitones equals one octave up; -12 equals one octave down. +- Playback duration stays the same regardless of the shift amount. +- Output format matches the input format. diff --git a/apps/docs/tools/pixelate.md b/apps/docs/tools/pixelate.md new file mode 100644 index 00000000..6514b192 --- /dev/null +++ b/apps/docs/tools/pixelate.md @@ -0,0 +1,66 @@ +--- +description: Apply a pixelation effect to the full image or a specific region. +--- + +# Pixelate + +Apply a pixelation effect to an entire image or a specific rectangular region. Useful for obscuring sensitive content like faces, license plates, or personal information. + +## API Endpoint + +`POST /api/v1/tools/pixelate` + +Accepts multipart form data with an image file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| blockSize | integer | No | `12` | Pixel block size (2-128); larger values produce coarser pixelation | +| region | object | No | - | Restrict pixelation to a rectangle (see below) | + +### Region Object + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| left | integer | Yes | Left offset in pixels (>= 0) | +| top | integer | Yes | Top offset in pixels (>= 0) | +| width | integer | Yes | Region width in pixels (>= 1) | +| height | integer | Yes | Region height in pixels (>= 1) | + +## Example Request + +Pixelate the full image: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/pixelate \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"blockSize": 20}' +``` + +Pixelate a specific region: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/pixelate \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"blockSize": 16, "region": {"left": 100, "top": 50, "width": 200, "height": 150}}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", + "originalSize": 2450000, + "processedSize": 2380000 +} +``` + +## Notes + +- When `region` is omitted, the entire image is pixelated. +- The region coordinates are in pixels relative to the top-left corner of the image. The region must fall within the image bounds. +- Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. diff --git a/apps/docs/tools/powerpoint-to-pdf.md b/apps/docs/tools/powerpoint-to-pdf.md new file mode 100644 index 00000000..3b6d643f --- /dev/null +++ b/apps/docs/tools/powerpoint-to-pdf.md @@ -0,0 +1,43 @@ +--- +description: Convert presentations to PDF. +--- + +# PowerPoint to PDF + +Convert PowerPoint or OpenDocument presentations to PDF, with one slide per page. + +## API Endpoint + +`POST /api/v1/tools/powerpoint-to-pdf` + +Accepts multipart form data with a PowerPoint/ODP file. + +## Parameters + +This tool has no configurable parameters. Upload a presentation and it will be converted to PDF. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/powerpoint-to-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@slides.pptx" +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input formats: `.pptx`, `.ppt`, `.odp`. +- Each slide becomes one page in the PDF. +- Conversion is handled by LibreOffice running headless on the server. +- Animations and transitions are not included in the PDF output. diff --git a/apps/docs/tools/protect-pdf.md b/apps/docs/tools/protect-pdf.md new file mode 100644 index 00000000..52dfe946 --- /dev/null +++ b/apps/docs/tools/protect-pdf.md @@ -0,0 +1,47 @@ +--- +description: Add password protection with AES-256 encryption to a PDF. +--- + +# Protect PDF + +Add password protection to a PDF using AES-256 encryption. + +## API Endpoint + +`POST /api/v1/tools/protect-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| userPassword | string | Yes | - | Password required to open the PDF (1-256 characters) | +| ownerPassword | string | No | Same as `userPassword` | Owner password for permissions (1-256 characters) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/protect-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"userPassword": "s3cret", "ownerPassword": "0wn3r"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2500000 +} +``` + +## Notes + +- Encryption uses AES-256. +- If `ownerPassword` is omitted, it defaults to the same value as `userPassword`. +- Passwords are redacted from audit logs. +- The encrypted PDF requires the user password to open and the owner password (if different) for full permissions. diff --git a/apps/docs/tools/redact-pdf.md b/apps/docs/tools/redact-pdf.md new file mode 100644 index 00000000..a449a3e4 --- /dev/null +++ b/apps/docs/tools/redact-pdf.md @@ -0,0 +1,49 @@ +--- +description: Permanently remove text occurrences from a PDF (verified true redaction). +--- + +# Redact PDF + +Permanently remove specified text occurrences from a PDF using verified true redaction. The redacted text is completely removed from the file, not just covered with a black box. + +## API Endpoint + +`POST /api/v1/tools/redact-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| terms | string[] | Yes | - | Text strings to redact (1-50 terms, each up to 200 characters) | +| caseSensitive | boolean | No | `false` | Whether matching is case-sensitive | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/redact-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@contract.pdf" \ + -F 'settings={"terms": ["John Doe", "555-0123"], "caseSensitive": false}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/contract.pdf", + "originalSize": 245000, + "processedSize": 243000, + "found": 7 +} +``` + +## Notes + +- Accepted input format: `.pdf`. +- This is a fast (synchronous) tool that returns the result directly. +- This performs true redaction: matched text is removed from the PDF content stream, not merely obscured visually. +- The `found` field in the response indicates how many occurrences were redacted. +- You can redact up to 50 terms in a single request. diff --git a/apps/docs/tools/remove-pages.md b/apps/docs/tools/remove-pages.md new file mode 100644 index 00000000..76b2dc5b --- /dev/null +++ b/apps/docs/tools/remove-pages.md @@ -0,0 +1,44 @@ +--- +description: Delete specific pages from a PDF. +--- + +# Remove Pages + +Delete specific pages from a PDF, keeping all remaining pages intact. + +## API Endpoint + +`POST /api/v1/tools/remove-pages` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| pages | string | Yes | - | Page range to remove in qpdf syntax, e.g. `"3,5-7"` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/remove-pages \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"pages": "3,5-7"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 1800000 +} +``` + +## Notes + +- You cannot remove every page from a document; at least one page must remain. +- Page ranges use qpdf syntax: `3` for a single page, `5-7` for a range, and commas to combine (e.g. `1,3,5-7`). diff --git a/apps/docs/tools/repair-pdf.md b/apps/docs/tools/repair-pdf.md new file mode 100644 index 00000000..c24e0d36 --- /dev/null +++ b/apps/docs/tools/repair-pdf.md @@ -0,0 +1,42 @@ +--- +description: Attempt to repair a damaged or corrupted PDF. +--- + +# Repair PDF + +Attempt to repair a damaged or corrupted PDF by reconstructing its internal structure. + +## API Endpoint + +`POST /api/v1/tools/repair-pdf` + +Accepts multipart form data with a PDF file. No `settings` field is required. + +## Parameters + +This tool has no settings parameters. Upload the damaged PDF file directly. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/repair-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@damaged.pdf" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/damaged.pdf", + "originalSize": 2450000, + "processedSize": 2400000 +} +``` + +## Notes + +- Structural validation is skipped on input to allow malformed files through. +- Repair is best-effort; severely corrupted files may not be fully recoverable. +- The repaired PDF may differ slightly in size from the original due to reconstructed cross-reference tables. diff --git a/apps/docs/tools/replace-audio.md b/apps/docs/tools/replace-audio.md new file mode 100644 index 00000000..92ecb05e --- /dev/null +++ b/apps/docs/tools/replace-audio.md @@ -0,0 +1,43 @@ +--- +description: Swap the audio track of a video with another file. +--- + +# Replace Audio + +Swap the audio track of a video with an audio file. Upload both a video and an audio file. + +## API Endpoint + +`POST /api/v1/tools/replace-audio` + +Accepts multipart form data with exactly two files: a video file followed by an audio file. + +## Parameters + +This tool has no settings parameters. Upload a video file and an audio file as two `file` parts. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/replace-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F "file=@voiceover.mp3" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 13100000 +} +``` + +## Notes + +- Exactly two files must be uploaded: the first must be a video, the second must be an audio file. +- If the audio file is longer than the video, it is trimmed to match the video duration. If shorter, the remaining video plays in silence. +- The video stream is copied without re-encoding, so there is no video quality loss. diff --git a/apps/docs/tools/resize-video.md b/apps/docs/tools/resize-video.md new file mode 100644 index 00000000..6c3ccd54 --- /dev/null +++ b/apps/docs/tools/resize-video.md @@ -0,0 +1,58 @@ +--- +description: Scale a video to a new resolution or preset size. +--- + +# Resize Video + +Scale a video to a new resolution using custom pixel dimensions or a standard preset. + +## API Endpoint + +`POST /api/v1/tools/resize-video` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| width | integer | No | - | Target width in pixels (16-7680) | +| height | integer | No | - | Target height in pixels (16-4320) | +| preset | string | No | `"custom"` | Resolution preset: `custom`, `2160p`, `1440p`, `1080p`, `720p`, `480p`, `360p` | + +When `preset` is `"custom"`, at least one of `width` or `height` must be provided. The other dimension scales proportionally. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/resize-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"preset": "720p"}' +``` + +Resize to custom dimensions: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/resize-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"width": 1280, "height": 720}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 25000000, + "processedSize": 8500000 +} +``` + +## Notes + +- Preset values map to standard heights (e.g. `720p` = 1280x720, `1080p` = 1920x1080). Width scales proportionally from the source aspect ratio. +- Dimensions are rounded to even numbers as required by most video codecs. +- Maximum supported resolution is 7680x4320 (8K UHD). diff --git a/apps/docs/tools/reverse-audio.md b/apps/docs/tools/reverse-audio.md new file mode 100644 index 00000000..44c24cb7 --- /dev/null +++ b/apps/docs/tools/reverse-audio.md @@ -0,0 +1,41 @@ +--- +description: Reverse an audio file so it plays backwards. +--- + +# Reverse Audio + +Reverse an audio file so it plays backwards. + +## API Endpoint + +`POST /api/v1/tools/reverse-audio` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +This tool has no configurable parameters. The entire audio file is reversed. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/reverse-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 4500000 +} +``` + +## Notes + +- The full audio track is reversed from end to start. +- Output format matches the input format. diff --git a/apps/docs/tools/reverse-video.md b/apps/docs/tools/reverse-video.md new file mode 100644 index 00000000..0c428332 --- /dev/null +++ b/apps/docs/tools/reverse-video.md @@ -0,0 +1,41 @@ +--- +description: Play a video clip backwards. +--- + +# Reverse Video + +Play a video clip backwards. The audio track is also reversed. + +## API Endpoint + +`POST /api/v1/tools/reverse-video` + +Accepts multipart form data with a video file. This tool has no configurable settings. + +## Parameters + +This tool has no parameters. It reverses the entire video. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/reverse-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 12600000 +} +``` + +## Notes + +- Limited to clips up to 5 minutes in length. Longer videos are rejected with a 400 error. +- Both video and audio tracks are reversed. To reverse video without audio, mute it first. diff --git a/apps/docs/tools/ringtone-maker.md b/apps/docs/tools/ringtone-maker.md new file mode 100644 index 00000000..5d8f276a --- /dev/null +++ b/apps/docs/tools/ringtone-maker.md @@ -0,0 +1,46 @@ +--- +description: Create a ringtone clip from any audio file. +--- + +# Ringtone Maker + +Create a ringtone clip (.m4r) from any audio file by selecting a start time and duration. + +## API Endpoint + +`POST /api/v1/tools/ringtone-maker` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| startS | number | No | `0` | Start time in seconds (minimum 0) | +| durationS | number | No | `30` | Clip duration in seconds (1 to 30) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/ringtone-maker \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"startS": 15, "durationS": 20}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.m4r", + "originalSize": 4500000, + "processedSize": 620000 +} +``` + +## Notes + +- Output is always M4R format, compatible with iPhone ringtones. +- Maximum ringtone duration is 30 seconds (Apple limit). +- Any audio format can be used as input. diff --git a/apps/docs/tools/rotate-pdf.md b/apps/docs/tools/rotate-pdf.md new file mode 100644 index 00000000..a42d6677 --- /dev/null +++ b/apps/docs/tools/rotate-pdf.md @@ -0,0 +1,46 @@ +--- +description: Rotate pages in a PDF by 90, 180, or 270 degrees. +--- + +# Rotate PDF + +Rotate all or selected pages in a PDF by a specified angle. + +## API Endpoint + +`POST /api/v1/tools/rotate-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| angle | integer | No | `90` | Rotation angle: `90`, `180`, or `270` | +| range | string | No | `"1-z"` | Page range in qpdf syntax, e.g. `"1-5,8"` (`"1-z"` = all pages) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/rotate-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"angle": 90, "range": "1-3"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2450000 +} +``` + +## Notes + +- Rotation is clockwise. +- Page ranges use qpdf syntax: `1-5` for pages 1 through 5, `z` for the last page, and commas to combine ranges. +- The default range `"1-z"` rotates all pages. diff --git a/apps/docs/tools/rotate-video.md b/apps/docs/tools/rotate-video.md new file mode 100644 index 00000000..9d9a827f --- /dev/null +++ b/apps/docs/tools/rotate-video.md @@ -0,0 +1,52 @@ +--- +description: Rotate or flip a video. +--- + +# Rotate Video + +Rotate a video by 90, 180, or 270 degrees, or flip it horizontally or vertically. + +## API Endpoint + +`POST /api/v1/tools/rotate-video` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| transform | string | Yes | - | Transformation to apply: `cw90`, `ccw90`, `180`, `hflip`, `vflip` | + +### Transform Values + +- **cw90** - Rotate 90 degrees clockwise +- **ccw90** - Rotate 90 degrees counter-clockwise +- **180** - Rotate 180 degrees +- **hflip** - Flip horizontally (mirror) +- **vflip** - Flip vertically + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/rotate-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"transform": "cw90"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 12400000 +} +``` + +## Notes + +- Rotations by 90 or 270 degrees swap the video's width and height. +- Flip operations (hflip, vflip) do not change the video dimensions. diff --git a/apps/docs/tools/silence-removal.md b/apps/docs/tools/silence-removal.md new file mode 100644 index 00000000..9734bbe6 --- /dev/null +++ b/apps/docs/tools/silence-removal.md @@ -0,0 +1,47 @@ +--- +description: Strip silent sections from an audio file. +--- + +# Silence Removal + +Detect and remove silent sections from an audio file based on a configurable threshold and minimum duration. + +## API Endpoint + +`POST /api/v1/tools/silence-removal` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| thresholdDb | number | No | `-50` | Silence threshold in dB (-80 to -20). Audio below this level is considered silent. | +| minSilenceS | number | No | `0.5` | Minimum silence duration in seconds to remove (0.1 to 5) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/silence-removal \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"thresholdDb": -45, "minSilenceS": 1}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 3200000 +} +``` + +## Notes + +- A higher (less negative) threshold is more aggressive and removes quieter passages as well as true silence. +- Increase `minSilenceS` to only strip longer pauses while keeping short natural gaps. +- Useful for cleaning up podcast recordings, lectures, and voice memos. +- Output format matches the input format. diff --git a/apps/docs/tools/split-audio.md b/apps/docs/tools/split-audio.md new file mode 100644 index 00000000..9bd2bfff --- /dev/null +++ b/apps/docs/tools/split-audio.md @@ -0,0 +1,61 @@ +--- +description: Split audio by time intervals, equal parts, or silence detection. +--- + +# Split Audio + +Split an audio file into segments by fixed time intervals, equal parts, or automatic silence detection. Returns a ZIP archive of the segments. + +## API Endpoint + +`POST /api/v1/tools/split-audio` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| mode | string | No | `"time"` | Split strategy: `time`, `parts`, `silence` | +| segmentS | number | No | `60` | Segment length in seconds, 1 to 3600 (used when mode is `time`) | +| parts | integer | No | `2` | Number of equal parts, 2 to 20 (used when mode is `parts`) | +| thresholdDb | number | No | `-40` | Silence threshold in dB, -80 to -20 (used when mode is `silence`) | +| minSilenceS | number | No | `0.3` | Minimum silence gap in seconds, 0.1 to 10 (used when mode is `silence`) | + +## Example Request + +Split into 30-second segments: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/split-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"mode": "time", "segmentS": 30}' +``` + +Split by silence detection: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/split-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"mode": "silence", "thresholdDb": -35, "minSilenceS": 0.5}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio-segments.zip", + "originalSize": 4500000, + "processedSize": 4600000 +} +``` + +## Notes + +- The `downloadUrl` points to a ZIP archive containing all segments. +- Only the parameters relevant to the chosen `mode` are used; others are ignored. +- Segment filenames are numbered sequentially (e.g. `001.mp3`, `002.mp3`). +- Output format matches the input format. diff --git a/apps/docs/tools/split-csv.md b/apps/docs/tools/split-csv.md new file mode 100644 index 00000000..6c310ea7 --- /dev/null +++ b/apps/docs/tools/split-csv.md @@ -0,0 +1,47 @@ +--- +description: Split a CSV into smaller files by row count. +--- + +# Split CSV + +Split a large CSV or TSV file into smaller files by row count. Returns a ZIP archive containing the parts. + +## API Endpoint + +`POST /api/v1/tools/split-csv` + +Accepts multipart form data with a CSV file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| rowsPerFile | integer | No | `1000` | Number of data rows per output file (1--1,000,000) | +| keepHeader | boolean | No | `true` | Repeat the header row in each output file | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/split-csv \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@large-dataset.csv" \ + -F 'settings={"rowsPerFile": 500, "keepHeader": true}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/large-dataset-split.zip", + "originalSize": 1048576, + "processedSize": 1050000 +} +``` + +## Notes + +- Output is always a ZIP archive containing the split CSV parts, named sequentially (e.g. `part-1.csv`, `part-2.csv`). +- When `keepHeader` is `true`, each part includes the original header row so each file can be used independently. +- Both CSV and TSV files are accepted as input. +- The row count refers to data rows only; the header row is not counted. diff --git a/apps/docs/tools/split-pdf.md b/apps/docs/tools/split-pdf.md new file mode 100644 index 00000000..2d269c56 --- /dev/null +++ b/apps/docs/tools/split-pdf.md @@ -0,0 +1,58 @@ +--- +description: Extract pages or split a PDF into parts. +--- + +# Split PDF + +Extract a range of pages into a new PDF, or split a document into chunks of N pages. + +## API Endpoint + +`POST /api/v1/tools/split-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| mode | string | No | `"range"` | Split mode: `range` or `every` | +| range | string | When mode is `range` | - | Page range in qpdf syntax, e.g. `"1-5,8,10-z"` | +| everyN | integer | When mode is `every` | - | Split into chunks of N pages (1-500) | + +## Example Request + +Extract specific pages: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/split-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"mode": "range", "range": "1-5,8"}' +``` + +Split into chunks of 10 pages: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/split-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"mode": "every", "everyN": 10}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 980000 +} +``` + +## Notes + +- In `range` mode, a single PDF containing the selected pages is returned. +- In `every` mode, the result is a ZIP archive containing the individual parts. +- Page ranges use qpdf syntax: `1-5` for pages 1 through 5, `z` for the last page, and commas to combine ranges (e.g. `1-3,7,10-z`). diff --git a/apps/docs/tools/sprite-sheet.md b/apps/docs/tools/sprite-sheet.md new file mode 100644 index 00000000..cbbbb4b5 --- /dev/null +++ b/apps/docs/tools/sprite-sheet.md @@ -0,0 +1,66 @@ +--- +description: Combine multiple images into a single sprite sheet grid with frame metadata. +--- + +# Sprite Sheet + +Combine multiple images into a single sprite sheet grid. Each image is resized to match the first image's dimensions and placed into the grid. Returns the sprite sheet image along with per-frame coordinate metadata. + +## API Endpoint + +`POST /api/v1/tools/sprite-sheet` + +Accepts multipart form data with two or more image files and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| columns | integer | No | `4` | Number of columns in the grid (1-16) | +| padding | integer | No | `0` | Padding between cells in pixels (0-64) | +| background | string | No | `"#ffffff"` | Background hex color | +| format | string | No | `"png"` | Output format: `png`, `webp`, or `jpeg` | +| quality | integer | No | `90` | Output quality (1-100) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/sprite-sheet \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@frame1.png" \ + -F "file=@frame2.png" \ + -F "file=@frame3.png" \ + -F "file=@frame4.png" \ + -F 'settings={"columns": 2, "padding": 4, "format": "png"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sprite-sheet.png", + "originalSize": 120000, + "processedSize": 95000, + "frames": [ + { "index": 0, "left": 0, "top": 0, "width": 128, "height": 128 }, + { "index": 1, "left": 132, "top": 0, "width": 128, "height": 128 }, + { "index": 2, "left": 0, "top": 132, "width": 128, "height": 128 }, + { "index": 3, "left": 132, "top": 132, "width": 128, "height": 128 } + ], + "cols": 2, + "rows": 2, + "cellWidth": 128, + "cellHeight": 128, + "canvasWidth": 260, + "canvasHeight": 260 +} +``` + +## Notes + +- Accepts 2 to 64 images. All images are resized to match the dimensions of the first uploaded image. +- The `frames` array provides the exact pixel coordinates of each frame in the output, suitable for CSS sprite definitions or game engine frame maps. +- The number of rows is calculated automatically from the image count and `columns` value. +- Use the `padding` parameter to add spacing between cells. The `background` color is visible in padding areas and any empty trailing cells. +- HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. diff --git a/apps/docs/tools/stabilize-video.md b/apps/docs/tools/stabilize-video.md new file mode 100644 index 00000000..9e748698 --- /dev/null +++ b/apps/docs/tools/stabilize-video.md @@ -0,0 +1,43 @@ +--- +description: Reduce camera shake with two-pass stabilization. +--- + +# Stabilize Video + +Reduce camera shake in handheld footage using FFmpeg's two-pass vidstab stabilization. + +## API Endpoint + +`POST /api/v1/tools/stabilize-video` + +Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| smoothing | integer | No | `15` | Smoothing window size in frames (5-60). Higher values produce smoother motion | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/stabilize-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"smoothing": 30}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Stabilization is a two-pass process: the first pass analyzes camera motion, and the second pass applies the correction. This takes roughly twice as long as single-pass tools. +- Higher smoothing values remove more shake but may introduce a slight zoom crop at the edges. +- Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. diff --git a/apps/docs/tools/to-epub.md b/apps/docs/tools/to-epub.md new file mode 100644 index 00000000..a42e0593 --- /dev/null +++ b/apps/docs/tools/to-epub.md @@ -0,0 +1,43 @@ +--- +description: Convert Word, Markdown, HTML, or plain text files to EPUB. +--- + +# Convert to EPUB + +Convert Word documents, Markdown, HTML, or plain text files into the EPUB e-book format. + +## API Endpoint + +`POST /api/v1/tools/to-epub` + +Accepts multipart form data with a Word/Markdown/HTML/TXT file. + +## Parameters + +This tool has no configurable parameters. Upload a document and it will be converted to EPUB. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/to-epub \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@manuscript.docx" +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input formats: `.docx`, `.md`, `.html`, `.txt`. +- The EPUB output follows the EPUB 3 specification. +- Headings in the source document are used to generate the table of contents. +- Conversion is handled by Pandoc on the server. diff --git a/apps/docs/tools/transcribe-audio.md b/apps/docs/tools/transcribe-audio.md new file mode 100644 index 00000000..44269dc5 --- /dev/null +++ b/apps/docs/tools/transcribe-audio.md @@ -0,0 +1,50 @@ +--- +description: Convert speech to text with AI-powered transcription. +--- + +# Transcribe Audio + +Convert speech to text using AI-powered transcription (faster-whisper). Supports plain text, SRT, and VTT output formats with automatic or manual language selection. + +## API Endpoint + +`POST /api/v1/tools/transcribe-audio` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| language | string | No | `"auto"` | Language: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko`, `id`, `th`, `vi` | +| outputFormat | string | No | `"txt"` | Output format: `txt`, `srt`, `vtt` | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/transcribe-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"language": "en", "outputFormat": "srt"}' +``` + +## Example Response + +This is an async tool. The API returns `202 Accepted` immediately: + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +Track progress via SSE at `GET /api/v1/jobs/{jobId}/progress`. When the job completes, the SSE stream delivers the final result with a `downloadUrl`. + +## Notes + +- Requires the **transcription** feature bundle to be installed. Returns `501 Not Implemented` if the bundle is not available. +- Uses faster-whisper for transcription. Language `auto` detects the spoken language automatically. +- `srt` and `vtt` formats include timestamps for each segment, suitable for subtitles. +- `txt` format returns plain text without timestamps. +- This is a long-running AI tool; processing time depends on audio length and server hardware. diff --git a/apps/docs/tools/trim-audio.md b/apps/docs/tools/trim-audio.md new file mode 100644 index 00000000..0cc4d0b3 --- /dev/null +++ b/apps/docs/tools/trim-audio.md @@ -0,0 +1,47 @@ +--- +description: Cut a section out of an audio file by specifying start and end times. +--- + +# Trim Audio + +Cut a section out of an audio file by specifying start and end times in seconds. + +## API Endpoint + +`POST /api/v1/tools/trim-audio` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| startS | number | No | `0` | Start time in seconds (minimum 0) | +| endS | number | Yes | - | End time in seconds (must be after start) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/trim-audio \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"startS": 10, "endS": 45}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 1575000 +} +``` + +## Notes + +- Times are specified in seconds and can include decimals (e.g. `10.5`). +- The `endS` value must be greater than `startS`. +- If `endS` exceeds the audio duration, the file is trimmed to the end. +- Output format matches the input format. diff --git a/apps/docs/tools/trim-video.md b/apps/docs/tools/trim-video.md new file mode 100644 index 00000000..1ef71893 --- /dev/null +++ b/apps/docs/tools/trim-video.md @@ -0,0 +1,47 @@ +--- +description: Cut a clip out of a video by specifying start and end times. +--- + +# Trim Video + +Cut a clip out of a video by specifying start and end times in seconds, with an option for frame-accurate cuts. + +## API Endpoint + +`POST /api/v1/tools/trim-video` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| startS | number | No | `0` | Start time in seconds (must be >= 0) | +| endS | number | Yes | - | End time in seconds (must be after startS) | +| precise | boolean | No | `false` | Re-encode for frame-accurate cuts instead of keyframe seek | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/trim-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"startS": 5, "endS": 30, "precise": true}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 4200000 +} +``` + +## Notes + +- When `precise` is `false` (the default), the tool uses keyframe seeking, which is fast but may start a few frames before the requested time. +- Setting `precise` to `true` re-encodes the segment for exact frame boundaries, but takes longer. +- The `endS` value must be greater than `startS`. diff --git a/apps/docs/tools/unlock-pdf.md b/apps/docs/tools/unlock-pdf.md new file mode 100644 index 00000000..22435175 --- /dev/null +++ b/apps/docs/tools/unlock-pdf.md @@ -0,0 +1,45 @@ +--- +description: Remove password protection from a PDF. +--- + +# Unlock PDF + +Remove password protection from an encrypted PDF by providing the correct password. + +## API Endpoint + +`POST /api/v1/tools/unlock-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| password | string | Yes | - | Password to decrypt the PDF (1-256 characters) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/unlock-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"password": "s3cret"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2500000, + "processedSize": 2450000 +} +``` + +## Notes + +- The correct password must be provided; an incorrect password returns a 400 error. +- Either the user password or the owner password will work for decryption. +- Passwords are redacted from audit logs. diff --git a/apps/docs/tools/video-color.md b/apps/docs/tools/video-color.md new file mode 100644 index 00000000..9fb11f94 --- /dev/null +++ b/apps/docs/tools/video-color.md @@ -0,0 +1,48 @@ +--- +description: Adjust brightness, contrast, saturation, and gamma of a video. +--- + +# Video Color + +Adjust brightness, contrast, saturation, and gamma correction on a video. + +## API Endpoint + +`POST /api/v1/tools/video-color` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| brightness | number | No | `0` | Brightness adjustment (-1 to 1) | +| contrast | number | No | `1` | Contrast multiplier (0-4) | +| saturation | number | No | `1` | Saturation multiplier (0-3). Set to 0 for grayscale | +| gamma | number | No | `1` | Gamma correction (0.1-10) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/video-color \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"brightness": 0.1, "contrast": 1.2, "saturation": 1.5}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 12300000 +} +``` + +## Notes + +- All values at their defaults (brightness 0, contrast 1, saturation 1, gamma 1) produce no change. +- Setting saturation to `0` converts the video to grayscale. +- Gamma values below 1 brighten shadows, while values above 1 darken them. diff --git a/apps/docs/tools/video-loudnorm.md b/apps/docs/tools/video-loudnorm.md new file mode 100644 index 00000000..b532987d --- /dev/null +++ b/apps/docs/tools/video-loudnorm.md @@ -0,0 +1,42 @@ +--- +description: Normalize video audio volume to broadcast standard. +--- + +# Normalize Audio + +Normalize video audio volume to the EBU R128 broadcast loudness standard. + +## API Endpoint + +`POST /api/v1/tools/video-loudnorm` + +Accepts multipart form data with a video file. This tool has no configurable settings. + +## Parameters + +This tool has no parameters. It applies EBU R128 loudness normalization to the audio track. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/video-loudnorm \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 12500000 +} +``` + +## Notes + +- Uses FFmpeg's two-pass `loudnorm` filter targeting -14 LUFS integrated loudness, the standard for streaming platforms. +- The source audio sample rate is preserved in the output. +- If the video has no audio track, the request returns a 400 error. diff --git a/apps/docs/tools/video-metadata.md b/apps/docs/tools/video-metadata.md new file mode 100644 index 00000000..760cd84c --- /dev/null +++ b/apps/docs/tools/video-metadata.md @@ -0,0 +1,42 @@ +--- +description: Strip metadata from a video and report what was found. +--- + +# Clean Video Metadata + +Strip metadata (creation date, GPS coordinates, camera model, software tags, etc.) from a video and report what was removed. + +## API Endpoint + +`POST /api/v1/tools/video-metadata` + +Accepts multipart form data with a video file. This tool has no configurable settings. + +## Parameters + +This tool has no parameters. It strips all metadata from the video container. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/video-metadata \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 12480000 +} +``` + +## Notes + +- Metadata stripped includes creation timestamps, GPS/location data, camera/device info, and software tags. +- The video and audio streams are copied without re-encoding, so there is no quality loss. +- Useful for privacy before sharing videos publicly. diff --git a/apps/docs/tools/video-speed.md b/apps/docs/tools/video-speed.md new file mode 100644 index 00000000..a9022072 --- /dev/null +++ b/apps/docs/tools/video-speed.md @@ -0,0 +1,46 @@ +--- +description: Speed up or slow down a video. +--- + +# Video Speed + +Speed up or slow down a video with an option to preserve audio pitch. + +## API Endpoint + +`POST /api/v1/tools/video-speed` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| factor | number | No | `2` | Speed multiplier (0.25-4). Values above 1 speed up, below 1 slow down | +| keepPitch | boolean | No | `true` | Preserve audio pitch when changing speed | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/video-speed \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"factor": 0.5, "keepPitch": true}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 24800000 +} +``` + +## Notes + +- A factor of `2` doubles playback speed (halves duration). A factor of `0.5` halves playback speed (doubles duration). +- When `keepPitch` is `true`, the audio is time-stretched so voices sound natural. When `false`, pitch shifts proportionally with speed. +- The valid range is 0.25x to 4x. diff --git a/apps/docs/tools/video-to-frames.md b/apps/docs/tools/video-to-frames.md new file mode 100644 index 00000000..bfc431ab --- /dev/null +++ b/apps/docs/tools/video-to-frames.md @@ -0,0 +1,59 @@ +--- +description: Extract frames from a video as a ZIP of images. +--- + +# Video to Frames + +Extract individual frames from a video and download them as a ZIP archive of PNG or JPG images. + +## API Endpoint + +`POST /api/v1/tools/video-to-frames` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| mode | string | No | `"all"` | Extraction mode: `all`, `nth`, `timestamps` | +| n | integer | No | `10` | Extract every Nth frame (2-1000). Only used when mode is `"nth"` | +| timestamps | string | No | `""` | Comma-separated timestamps in seconds. Required when mode is `"timestamps"` | +| format | string | No | `"png"` | Image format for extracted frames: `png`, `jpg` | + +## Example Request + +Extract every 30th frame as JPG: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/video-to-frames \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"mode": "nth", "n": 30, "format": "jpg"}' +``` + +Extract frames at specific timestamps: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/video-to-frames \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"mode": "timestamps", "timestamps": "1.5,5,12.3"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip-frames.zip", + "originalSize": 12500000, + "processedSize": 45000000 +} +``` + +## Notes + +- The `all` mode extracts every frame and can produce very large ZIP files for long videos. Use `nth` or `timestamps` mode for selective extraction. +- PNG preserves full quality but produces larger files. JPG is smaller but lossy. +- The response downloads as a ZIP archive containing sequentially numbered image files. diff --git a/apps/docs/tools/video-to-gif.md b/apps/docs/tools/video-to-gif.md new file mode 100644 index 00000000..6ddf37db --- /dev/null +++ b/apps/docs/tools/video-to-gif.md @@ -0,0 +1,46 @@ +--- +description: Turn a video clip into an animated GIF. +--- + +# Video to GIF + +Turn a video clip into an animated GIF with configurable frame rate, width, start time, and duration. + +## API Endpoint + +`POST /api/v1/tools/video-to-gif` + +Accepts multipart form data with a video file and a JSON `settings` field. This is an async endpoint - it returns `202 Accepted` immediately and progress is streamed via SSE at `GET /api/v1/jobs/{jobId}/progress`. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| fps | integer | No | `12` | Output frame rate (1-30) | +| width | integer | No | `480` | Output width in pixels (64-1280). Height scales proportionally | +| startS | number | No | `0` | Start time in seconds (must be >= 0) | +| durationS | number | No | `5` | Duration in seconds (0-60) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/video-to-gif \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"fps": 15, "width": 320, "startS": 2, "durationS": 8}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Lower `fps` and `width` values produce smaller GIF files. A 480px-wide GIF at 12 fps is usually a good balance. +- Maximum duration is 60 seconds. Longer clips produce very large files. +- Progress updates are available via SSE at `GET /api/v1/jobs/{jobId}/progress` until the job completes. diff --git a/apps/docs/tools/video-to-webp.md b/apps/docs/tools/video-to-webp.md new file mode 100644 index 00000000..895d9659 --- /dev/null +++ b/apps/docs/tools/video-to-webp.md @@ -0,0 +1,48 @@ +--- +description: Convert a video clip into an animated WebP image. +--- + +# Video to WebP + +Convert a video clip into an animated WebP image with configurable frame rate, width, and quality. + +## API Endpoint + +`POST /api/v1/tools/video-to-webp` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| fps | integer | No | `12` | Output frame rate (1-30) | +| width | integer | No | `480` | Output width in pixels (16-1920). Height scales proportionally | +| quality | integer | No | `75` | WebP compression quality (1-100) | +| loop | boolean | No | `true` | Loop the animation | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/video-to-webp \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"fps": 15, "width": 640, "quality": 80}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.webp", + "originalSize": 12500000, + "processedSize": 2800000 +} +``` + +## Notes + +- Animated WebP produces smaller files than GIF with better color support (24-bit vs 8-bit palette). +- Lower `quality` values produce smaller files at the cost of visual fidelity. +- Set `loop` to `false` for animations that should play once and stop. diff --git a/apps/docs/tools/vignette.md b/apps/docs/tools/vignette.md new file mode 100644 index 00000000..e6576c61 --- /dev/null +++ b/apps/docs/tools/vignette.md @@ -0,0 +1,52 @@ +--- +description: Add a vignette effect with adjustable strength, color, and position. +--- + +# Vignette + +Add a vignette effect that darkens or tints the edges of an image. Supports adjustable strength, color, radius, softness, roundness, and center position. + +## API Endpoint + +`POST /api/v1/tools/vignette` + +Accepts multipart form data with an image file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| strength | number | No | `0.5` | Vignette opacity (0.1-1) | +| color | string | No | `"#000000"` | Vignette hex color | +| radius | integer | No | `70` | Outer radius as percentage of half-diagonal (0-100) | +| softness | integer | No | `50` | Feather softness (0-100); higher values produce a more gradual fade | +| roundness | integer | No | `100` | Shape: 100 = circle, 0 = ellipse matching image aspect ratio | +| centerX | integer | No | `50` | Horizontal center position as percentage (0-100) | +| centerY | integer | No | `50` | Vertical center position as percentage (0-100) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/vignette \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@photo.jpg" \ + -F 'settings={"strength": 0.7, "radius": 60, "softness": 70}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg", + "originalSize": 2450000, + "processedSize": 2410000 +} +``` + +## Notes + +- A smaller `radius` darkens more of the image; a larger radius confines the vignette to the extreme edges. +- Use a non-black `color` (e.g., white or sepia tones) for creative vignette effects. +- Adjusting `centerX` and `centerY` lets you position the clear area off-center, useful for drawing focus to a subject that is not in the middle of the frame. +- Output format matches the input format. HEIC, RAW, PSD, and SVG inputs are automatically decoded before processing. diff --git a/apps/docs/tools/volume-adjust.md b/apps/docs/tools/volume-adjust.md new file mode 100644 index 00000000..97c1f201 --- /dev/null +++ b/apps/docs/tools/volume-adjust.md @@ -0,0 +1,45 @@ +--- +description: Increase or decrease audio volume by a fixed gain in decibels. +--- + +# Volume Adjust + +Increase or decrease the volume of an audio file by applying a fixed gain in decibels. + +## API Endpoint + +`POST /api/v1/tools/volume-adjust` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| gainDb | number | No | `3` | Volume adjustment in decibels (-30 to 30) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/volume-adjust \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"gainDb": 6}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.mp3", + "originalSize": 4500000, + "processedSize": 4500000 +} +``` + +## Notes + +- Positive values increase volume; negative values decrease it. +- Large positive gains can cause clipping. Use normalize-audio for loudness-safe leveling. +- Output format matches the input format. diff --git a/apps/docs/tools/watermark-pdf.md b/apps/docs/tools/watermark-pdf.md new file mode 100644 index 00000000..bbb6009f --- /dev/null +++ b/apps/docs/tools/watermark-pdf.md @@ -0,0 +1,55 @@ +--- +description: Add a text watermark to every page of a PDF. +--- + +# Watermark PDF + +Stamp a text watermark on every page of a PDF with configurable position, size, opacity, and rotation. + +## API Endpoint + +`POST /api/v1/tools/watermark-pdf` + +Accepts multipart form data with a PDF file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| text | string | Yes | - | Watermark text (1-200 characters) | +| position | string | No | `"c"` | Placement on the page: `tl`, `tc`, `tr`, `l`, `c`, `r`, `bl`, `bc`, `br` | +| fontSize | integer | No | `48` | Font size in points (6-72) | +| opacity | number | No | `0.3` | Watermark opacity (0.05-1) | +| rotation | number | No | `45` | Rotation angle in degrees (-180 to 180) | + +### Position Values + +- `tl` top-left, `tc` top-center, `tr` top-right +- `l` center-left, `c` center, `r` center-right +- `bl` bottom-left, `bc` bottom-center, `br` bottom-right + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/watermark-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@document.pdf" \ + -F 'settings={"text": "CONFIDENTIAL", "position": "c", "opacity": 0.2, "rotation": 45}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/document.pdf", + "originalSize": 2450000, + "processedSize": 2500000 +} +``` + +## Notes + +- The watermark is rendered as a text overlay on each page. +- The same watermark text, position, and style are applied uniformly to all pages. +- Use lower opacity values (0.1-0.3) for subtle watermarks that do not obscure content. diff --git a/apps/docs/tools/watermark-video.md b/apps/docs/tools/watermark-video.md new file mode 100644 index 00000000..13ca28c4 --- /dev/null +++ b/apps/docs/tools/watermark-video.md @@ -0,0 +1,55 @@ +--- +description: Burn a text watermark onto video frames. +--- + +# Watermark Video + +Burn a text watermark onto every frame of a video with configurable position, size, opacity, and color. + +## API Endpoint + +`POST /api/v1/tools/watermark-video` + +Accepts multipart form data with a video file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| text | string | Yes | - | Watermark text (1-200 characters) | +| position | string | No | `"br"` | Position on the frame: `tl`, `tc`, `tr`, `l`, `c`, `r`, `bl`, `bc`, `br` | +| fontSize | integer | No | `36` | Font size in pixels (8-120) | +| opacity | number | No | `0.5` | Watermark opacity (0.05-1) | +| color | string | No | `"#ffffff"` | Hex color for the text (e.g. `"#ffffff"`) | + +### Position Values + +- **tl** - Top left, **tc** - Top center, **tr** - Top right +- **l** - Middle left, **c** - Center, **r** - Middle right +- **bl** - Bottom left, **bc** - Bottom center, **br** - Bottom right + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/watermark-video \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@clip.mp4" \ + -F 'settings={"text": "PREVIEW", "position": "c", "fontSize": 48, "opacity": 0.3}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/clip.mp4", + "originalSize": 12500000, + "processedSize": 12400000 +} +``` + +## Notes + +- The watermark is permanently rendered into the video frames and cannot be removed after processing. +- The watermark uses a sans-serif font built into FFmpeg. +- For image watermarks, use the image Watermark tool instead. diff --git a/apps/docs/tools/waveform-image.md b/apps/docs/tools/waveform-image.md new file mode 100644 index 00000000..bb269c2d --- /dev/null +++ b/apps/docs/tools/waveform-image.md @@ -0,0 +1,47 @@ +--- +description: Generate a waveform visualization as a PNG image from an audio file. +--- + +# Waveform Image + +Generate a waveform visualization as a PNG image from an audio file, with configurable dimensions and color. + +## API Endpoint + +`POST /api/v1/tools/waveform-image` + +Accepts multipart form data with an audio file and a JSON `settings` field. + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| width | integer | No | `1024` | Image width in pixels (256 to 3840) | +| height | integer | No | `256` | Image height in pixels (64 to 1080) | +| color | string | No | `"#4f46e5"` | Waveform hex color (e.g. `"#4f46e5"`) | + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/waveform-image \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@audio.mp3" \ + -F 'settings={"width": 1920, "height": 400, "color": "#e07832"}' +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/audio.png", + "originalSize": 4500000, + "processedSize": 45000 +} +``` + +## Notes + +- The output is always a PNG image, regardless of the input audio format. +- The waveform is rendered on a transparent background. +- Useful for thumbnails, social media previews, or embedding in web pages. diff --git a/apps/docs/tools/word-to-pdf.md b/apps/docs/tools/word-to-pdf.md new file mode 100644 index 00000000..ea7dead8 --- /dev/null +++ b/apps/docs/tools/word-to-pdf.md @@ -0,0 +1,43 @@ +--- +description: Convert Word documents to PDF. +--- + +# Word to PDF + +Convert Word documents, OpenDocument text, RTF, or plain text files to PDF. + +## API Endpoint + +`POST /api/v1/tools/word-to-pdf` + +Accepts multipart form data with a Word/ODT/RTF/TXT file. + +## Parameters + +This tool has no configurable parameters. Upload a document and it will be converted to PDF. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/word-to-pdf \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@report.docx" +``` + +## Example Response + +Returns `202 Accepted`. Track progress via SSE at `/api/v1/jobs/{jobId}/progress`. + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "async": true +} +``` + +## Notes + +- Accepted input formats: `.docx`, `.doc`, `.odt`, `.rtf`, `.txt`. +- Conversion is handled by LibreOffice running headless on the server. +- Fonts embedded in the document are used when available; otherwise system fonts are substituted. +- Headers, footers, tables, and images are preserved in the PDF output. diff --git a/apps/docs/tools/xml-to-csv.md b/apps/docs/tools/xml-to-csv.md new file mode 100644 index 00000000..39136165 --- /dev/null +++ b/apps/docs/tools/xml-to-csv.md @@ -0,0 +1,43 @@ +--- +description: Extract repeating elements from XML into a CSV table. +--- + +# XML to CSV + +Extract repeating elements from an XML file into a flat CSV table. The tool automatically finds the first array of objects in the XML tree and maps each element to a row. + +## API Endpoint + +`POST /api/v1/tools/xml-to-csv` + +Accepts multipart form data with an XML file. No settings field is required. + +## Parameters + +This tool has no configurable parameters. The repeating element is auto-detected from the XML structure. + +## Example Request + +```bash +curl -X POST http://localhost:1349/api/v1/tools/xml-to-csv \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@catalog.xml" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/catalog.csv", + "originalSize": 4500, + "processedSize": 1800 +} +``` + +## Notes + +- Only `.xml` files are accepted as input. +- The tool scans the XML tree for the first repeating set of sibling elements and uses those as rows. +- Each unique child element or attribute name becomes a CSV column header. +- This is a one-way conversion. For bidirectional JSON/XML conversion, use the [JSON to XML](/tools/json-xml) tool. diff --git a/apps/docs/tools/yaml-json.md b/apps/docs/tools/yaml-json.md new file mode 100644 index 00000000..a8607225 --- /dev/null +++ b/apps/docs/tools/yaml-json.md @@ -0,0 +1,52 @@ +--- +description: Convert between YAML and JSON, both directions. +--- + +# YAML / JSON + +Convert between YAML and JSON formats in both directions. Upload a YAML file to get JSON, or upload a JSON file to get YAML. + +## API Endpoint + +`POST /api/v1/tools/yaml-json` + +Accepts multipart form data with a YAML or JSON file. No settings field is required. + +## Parameters + +This tool has no configurable parameters. The conversion direction is determined by the input file extension. + +## Example Request + +YAML to JSON: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/yaml-json \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@config.yaml" +``` + +JSON to YAML: + +```bash +curl -X POST http://localhost:1349/api/v1/tools/yaml-json \ + -H "Authorization: Bearer si_your-api-key" \ + -F "file=@config.json" +``` + +## Example Response + +```json +{ + "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "downloadUrl": "/api/v1/download/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config.json", + "originalSize": 620, + "processedSize": 780 +} +``` + +## Notes + +- Conversion direction is auto-detected from the input file extension: `.yaml` or `.yml` produces `.json`, and `.json` produces `.yaml`. +- Both `.yaml` and `.yml` extensions are accepted. +- Multi-document YAML files (separated by `---`) are supported. diff --git a/package.json b/package.json index 2b3944e3..d934706d 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "@babel/core": ">=7.29.6", "@opentelemetry/core": ">=2.8.0", "js-yaml": ">=4.2.0", + "gray-matter>js-yaml": "^3.14.1", "qs": ">=6.15.2", "uuid": ">=11.1.1", "yaml": ">=2.8.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 06a105b3..42bf41c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,6 +24,7 @@ overrides: '@babel/core': '>=7.29.6' '@opentelemetry/core': '>=2.8.0' js-yaml: '>=4.2.0' + gray-matter>js-yaml: ^3.14.1 qs: '>=6.15.2' uuid: '>=11.1.1' yaml: '>=2.8.3' @@ -3928,6 +3929,9 @@ packages: arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -4842,6 +4846,11 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -5506,6 +5515,10 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + js-yaml@4.2.0: resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} hasBin: true @@ -7264,6 +7277,9 @@ packages: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + ssh-remote-port-forward@1.0.4: resolution: {integrity: sha512-x0LV1eVDwjf1gmG7TTnfqIzf+3VPRz7vrNIjX6oYLbeCrf/PeVY6hkT68Mg+q02qXxQhrLjB0jfgvhevoCRmLQ==} @@ -12234,6 +12250,10 @@ snapshots: arg@5.0.2: {} + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + argparse@2.0.1: {} argv-formatter@1.0.0: {} @@ -13112,6 +13132,8 @@ snapshots: escape-string-regexp@5.0.0: {} + esprima@4.0.1: {} + estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -13507,7 +13529,7 @@ snapshots: gray-matter@4.0.3: dependencies: - js-yaml: 4.2.0 + js-yaml: 3.14.2 kind-of: 6.0.3 section-matter: 1.0.0 strip-bom-string: 1.0.0 @@ -13892,6 +13914,11 @@ snapshots: js-tokens@9.0.1: {} + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + js-yaml@4.2.0: dependencies: argparse: 2.0.1 @@ -15872,6 +15899,8 @@ snapshots: split2@4.2.0: {} + sprintf-js@1.0.3: {} + ssh-remote-port-forward@1.0.4: dependencies: '@types/ssh2': 0.5.52