All tools
162 tools in 10 groups. Every one runs on your machine. Click a tool for its inputs and an example.
Merge, split, organise, compress, watermark, number, sign and fill PDFs; text and images out.
pdf_compressCompress PDF
Shrink a PDF by re-rendering every page as a JPEG image (best for scans and photo-heavy files). Presets like the website: email (96 DPI, quality 55), balanced (144 DPI, 72), high (220 DPI, 85); or set dpi/quality yourself; optional grayscale. The result loses selectable text, links and form fields. Reports before/after size and a verdict ("bigger" means keep the original: the PDF was already efficient). Web version: https://s3eidat.github.io/pdf-compress/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
preset | "email" | "balanced" | "high" default "balanced" | Quality preset. Default "balanced". |
dpi | integer | Override the preset resolution (36-300 DPI). |
quality | integer | Override the preset JPEG quality (30-95). |
grayscale | boolean default false | Convert pages to grayscale. |
password | string | Password, if the PDF is protected. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: small enough to attach to an email
{
"file": "scan.pdf",
"preset": "email"
}pdf_extract_pagesExtract PDF pages
Make one new PDF from selected pages of a PDF, e.g. "1-3, 7, 10-" (order as written, each page once). The rest of the file is left out. To reorder, duplicate or delete pages use pdf_organize. Web version: https://s3eidat.github.io/pdf-split/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
pages required | string | Pages to keep: "1-3, 7, 10-" ("5-" = to the end; also "odd", "even", "last"). |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: writes report-pages-1-3_7.pdf
{
"file": "report.pdf",
"pages": "1-3, 7"
}pdf_form_fieldsList PDF form fields
List the fillable fields of a PDF form in reading order: name, readable label, type (text, checkbox, radio, dropdown, list, signature, button), page, current value, options, and whether it is required / read-only / multi-line. Use the names with pdf_form_fill. Web version: https://s3eidat.github.io/pdf-fill/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
Example
{
"file": "application.pdf"
}pdf_form_fillFill a PDF form
Fill PDF form fields by name (get names from pdf_form_fields): text as strings, checkboxes as true/false, radio groups and dropdowns by option text, lists as arrays. Optionally flatten (bake the answers into the page, no longer editable). Only changed fields are redrawn. Text the standard font cannot draw (Arabic…) is kept and viewers are asked to draw it, but cannot be flattened. Web version: https://s3eidat.github.io/pdf-fill/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
values required | object | Field name -> value, e.g. {"name": "Sara", "agree": true, "plan": "pro", "langs": ["Arabic"]}. |
flatten | boolean default false | Flatten the form after filling (fields become plain page content). |
ignoreUnknown | boolean default false | Skip names that are not in the form instead of failing. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example
{
"file": "application.pdf",
"values": {
"name": "Sara Haddad",
"agree": true,
"plan": "pro",
"country": "Egypt"
},
"flatten": true
}pdf_from_imagesImages to PDF
Make a PDF from images (JPEG, PNG, WebP, GIF, TIFF, AVIF, SVG…), one image per page, in the order given. Page size A4, Letter, or "fit" (page = image size at 96 dpi); orientation auto/portrait/landscape; margin in mm; quality "original" (JPEG/PNG kept as-is), high (≤3000 px, JPEG 90), medium (≤2000 px, 75) or small (≤1400 px, 60). Photos are turned upright from their EXIF orientation. Web version: https://s3eidat.github.io/images-to-pdf/
| Input | Type | Description |
|---|---|---|
images required | (string | object)[] | Images in page order: path/base64 strings, or {file, rotate}. |
pageSize | "a4" | "letter" | "fit" default "a4" | Page size. Default "a4". |
orientation | "auto" | "portrait" | "landscape" default "auto" | "auto" turns the page to match each image. Ignored for "fit". |
margin | number default 10 | Margin around each image in mm. Default 10. |
quality | "original" | "high" | "medium" | "small" default "high" | Image quality / size trade-off. Default "high". |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example
{
"images": [
"receipt1.jpg",
"receipt2.jpg"
],
"output": "receipts.pdf"
}Example
{
"images": [
"scan.png",
{
"file": "photo.jpg",
"rotate": 90
}
],
"pageSize": "fit",
"margin": 0,
"quality": "original"
}pdf_infoPDF info
Quick facts about a PDF for planning the next step: page count, page sizes (points, mm, paper name such as "A4 portrait", grouped by size), rotated pages, encryption, PDF version, form field count, title/author, and which pages have no text layer (scans that would need OCR). Related web tool: https://s3eidat.github.io/pdf-metadata/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
password | string | Password, for the text check on a protected PDF. |
textCheck | boolean default true | Check which pages have a text layer (reads up to 500 pages). Default true. |
Example: { pages: 12, sizes: [{ paper: "A4 portrait", pages: "1-12" }], pagesWithoutText: [1, …] }
{
"file": "scan.pdf"
}pdf_mergeMerge PDFs
Combine several PDFs into one, in the order given. Each entry can be a file (path or base64) or {file, pages} to take only some pages ("1-3, 5, 8-"; "3-1" keeps reverse order; a page can repeat). Password-protected PDFs must be unlocked first. Web version: https://s3eidat.github.io/pdf-merge/
| Input | Type | Description |
|---|---|---|
files required | (string | object)[] | PDFs to merge, in order: a path/base64 string, or {file, pages}. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: report + pages 2-4 of the appendix
{
"files": [
"report.pdf",
{
"file": "appendix.pdf",
"pages": "2-4"
}
],
"output": "merged.pdf"
}pdf_metadata_readRead PDF metadata
Show what a PDF reveals about itself: Title, Author, Subject, Keywords, Creator, Producer, creation/modification dates (with time zone), custom info fields, XMP metadata (size, edit history, creator) and the document ID. Optionally returns the XMP XML. Web version: https://s3eidat.github.io/pdf-metadata/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
includeXmp | boolean default false | Also return the decoded XMP XML. |
Example
{
"file": "contract.pdf"
}pdf_metadata_writeEdit or strip PDF metadata
Change PDF info fields (title, author, subject, keywords, creator, producer, dates, custom fields) or strip all metadata: info fields, XMP, page-level data and the document ID, and drop unreachable leftovers from earlier edits so no trace stays in the bytes. Untouched values keep their exact original form. Web version: https://s3eidat.github.io/pdf-metadata/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
strip | boolean default false | Remove ALL metadata (other edits are ignored). |
title | string | Title. "" removes it; omit to keep it. |
author | string | Author. "" removes it; omit to keep it. |
subject | string | Subject. "" removes it; omit to keep it. |
keywords | string | Keywords. "" removes it; omit to keep it. |
creator | string | Creator (the app that made it). "" removes it; omit to keep it. |
producer | string | Producer (the PDF engine). "" removes it; omit to keep it. |
creationDate | string | Creation date as ISO 8601, e.g. "2026-03-14T09:30:00+03:00". "" removes it; omit to keep it. |
modDate | string | Modification date as ISO 8601. "" removes it; omit to keep it. |
custom | object | Custom info fields to set; null removes one. E.g. {"Company": null}. |
removeXmp | boolean default false | Remove the XMP metadata stream (and page-level XMP/PieceInfo). |
removeDocumentId | boolean default false | Remove the document ID from the trailer. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example
{
"file": "report.pdf",
"title": "Final report",
"author": "Sara Haddad"
}Example: writes cv-clean.pdf with no metadata
{
"file": "cv.pdf",
"strip": true
}pdf_organizeOrganize PDF pages
Rebuild a PDF from a page list: reorder, delete (leave pages out), duplicate (list a page twice) and insert blank pages. "3, 1-2, blank, 5-" puts page 3 first, then 1-2, a blank page (same size as the page before it), then 5 to the end; page 4 is dropped. Optionally rotate pages of the result. Existing page rotation is kept. Web version: https://s3eidat.github.io/pdf-organizer/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
pages required | string | New page order (1-based source pages): e.g. "3, 1-2, blank, 2, 5-". Pages not listed are removed; "blank" adds an empty page. |
rotate | object[] | Optional rotations applied to pages of the new order. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: swap the first two pages, turn page 3
{
"file": "scan.pdf",
"pages": "2, 1, 3-",
"rotate": [
{
"pages": "3",
"angle": 90
}
]
}pdf_page_numbersAdd page numbers
Add page numbers to a PDF, plus an optional header and footer line. Format tokens: {n}, {total}, {date}, {filename} (e.g. "Page {n} of {total}", "{n} / {total}", "- {n} -"). Choose the corner/edge, start number, how many leading pages to skip (e.g. a cover), a page range, font, size, colour and margin. Numbers stay upright on rotated pages. Web version: https://s3eidat.github.io/pdf-page-numbers/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
format | string default "Page {n} of {total}" | Number format with {n}, {total}, {date}, {filename}. Default "Page {n} of {total}". Empty = no number (header/footer only). |
position | "tl" | "tc" | "tr" | "bl" | "bc" | "br" default "bc" | Where the number goes: t/b = top/bottom, l/c/r = left/centre/right. Default "bc". |
start | integer default 1 | Number of the first numbered page. Default 1. |
skip | integer default 0 | Leave this many first pages without a number (e.g. 1 for a cover). Default 0. |
pages | string | Pages to number: 1-based list like "1-3, 5, 8-" ("5-" = to the end, "-3" = first three, "3-1" = reversed). Also "all", "odd", "even", "last". Empty = all pages. |
font | "Helvetica" | "HelveticaBold" | "TimesRoman" | "Courier" default "Helvetica" | |
size | number default 10 | Text size in points. Default 10. |
color | string default "#333333" | Colour as hex "#rrggbb". Default #333333. |
margin | number default 28 | Distance from the page edge in points. Default 28. |
header | string default "" | Optional header text on numbered pages (tokens allowed). |
headerAlign | "l" | "c" | "r" default "c" | Header alignment: l, c or r. |
footer | string default "" | Optional footer text on numbered pages (tokens allowed). |
footerAlign | "l" | "c" | "r" default "c" | Footer alignment: l, c or r. |
date | string | Text for {date}. Default: today in the server locale. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: no number on the cover
{
"file": "report.pdf",
"format": "Page {n} of {total}",
"position": "br",
"skip": 1
}Example
{
"file": "thesis.pdf",
"format": "{n}",
"footer": "Draft, {date}",
"footerAlign": "l"
}pdf_rotateRotate PDF pages
Rotate selected pages of a PDF by 90, 180 or 270 degrees clockwise (-90 = counter-clockwise), on top of any rotation they already have. Other pages, links and form fields are left as they are. Web version: https://s3eidat.github.io/pdf-organizer/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
angle required | 90 | 180 | 270 | -90 | Clockwise degrees: 90, 180, 270, or -90. |
pages | string | Pages to rotate: 1-based list like "1-3, 5, 8-" ("5-" = to the end, "-3" = first three, "3-1" = reversed). Also "all", "odd", "even", "last". Empty = all pages. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example
{
"file": "scan.pdf",
"angle": 90,
"pages": "even"
}pdf_sign_imageSign PDF with an image
Place a signature (or initials, stamp, logo) image on PDF pages at x/y/width in points, measured from the top-left of the page as it is shown (rotated pages are handled). A light paper background is removed by default so scanned signatures sit cleanly on the page. Optional text marks (name, date…) can be added too. This is a visual signature, not a cryptographic digital signature. To draw a signature by hand, use the web version: https://s3eidat.github.io/pdf-sign/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
signature | string | Signature image: local path or base64 (PNG, JPEG, WebP…). |
pages | string default "last" | Pages to sign: "last" (default), "1", "all", "1-3"… |
x | number default 72 | Left edge in points from the left of the page (72 pt = 1 inch). Default 72. |
y | number | Top edge in points from the TOP of the page. Default: 72 pt above the bottom margin. |
width | number default 150 | Width in points. Default 150 (about 5.3 cm). |
height | number | Height in points. Default: keeps the image aspect ratio. |
removeBackground | boolean default true | Make light (paper) pixels transparent and trim to the ink. Default true. |
threshold | integer default 210 | Brightness (0-255) above which pixels become transparent. Default 210. |
texts | object[] | Optional text marks, e.g. the printed name or the date. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example
{
"file": "contract.pdf",
"signature": "signature.png",
"pages": "last",
"x": 360,
"y": 700,
"width": 160
}Example
{
"file": "form.pdf",
"signature": "sig.jpg",
"pages": "2",
"x": 80,
"y": 620,
"texts": [
{
"text": "29/10/2026",
"page": 2,
"x": 300,
"y": 640
}
]
}pdf_splitSplit PDF
Split one PDF into several PDFs written to a folder: by page ranges (one file per range, e.g. "1-3, 4-6, 7-"), every N pages, or one file per page. Files are named like the website: <name>-pages-1-3.pdf, <name>-part-01.pdf, <name>-page-001.pdf. Use pdf_extract_pages to get a single PDF with chosen pages. Web version: https://s3eidat.github.io/pdf-split/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
mode required | "ranges" | "every" | "single" | "ranges": one PDF per range in `ranges`; "every": a new PDF every `every` pages; "single": one PDF per page. |
ranges | string | For mode "ranges": comma-separated ranges, each becomes one PDF, e.g. "1-3, 4-6, 7-". |
every | integer | For mode "every": pages per file (e.g. 2 makes 1-2, 3-4…). |
output | string | Folder to write the PDFs into (created if missing). Default: a new folder in the server output folder. |
Example: three PDFs
{
"file": "book.pdf",
"mode": "ranges",
"ranges": "1-10, 11-20, 21-"
}Example
{
"file": "scans.pdf",
"mode": "every",
"every": 2
}pdf_to_imagesPDF to images
Render PDF pages to PNG, JPEG or WebP images in a folder (one file per page, named <name>-p001.png…). Choose the DPI (72 = screen size, 150 = default, 300 = print), JPEG/WebP quality, a page range, and a transparent background for PNG/WebP. Very large pages are capped at 16384 px a side / 16.7 megapixels, like the website. Web version: https://s3eidat.github.io/pdf-to-images/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
format | "png" | "jpeg" | "webp" default "png" | Image format. Default "png". |
dpi | number default 150 | Resolution in dots per inch. Default 150. |
quality | integer default 90 | JPEG/WebP quality 1-100. Default 90. |
transparent | boolean default false | Keep the page background transparent (PNG/WebP only). |
pages | string | Pages to render: 1-based list like "1-3, 5, 8-" ("5-" = to the end, "-3" = first three, "3-1" = reversed). Also "all", "odd", "even", "last". Empty = all pages. |
password | string | Password, if the PDF is protected. |
output | string | Folder to write the images into (created if missing). Default: a new folder in the server output folder. |
Example
{
"file": "slides.pdf",
"format": "jpeg",
"dpi": 96,
"pages": "1-5"
}Example
{
"file": "logo.pdf",
"format": "png",
"dpi": 300,
"transparent": true
}pdf_to_textPDF to text
Extract the text of a PDF with lines and paragraphs rebuilt (right-to-left Arabic/Hebrew lines in reading order), as plain text or Markdown, with optional page separators and reflow (join lines, mend hyphenated words). Returns per-page word counts and flags pages with no text layer (scans: this tool does no OCR). Supports page ranges and passwords. Give "output" to write a .txt/.md file instead of returning the text inline. Web version: https://s3eidat.github.io/pdf-to-text/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
pages | string | Pages to read: 1-based list like "1-3, 5, 8-" ("5-" = to the end, "-3" = first three, "3-1" = reversed). Also "all", "odd", "even", "last". Empty = all pages. |
password | string | Password, if the PDF is protected. |
format | "text" | "markdown" default "text" | "text" or "markdown" (## Page N headings, reflowed paragraphs). |
separators | boolean default true | Put a "——— Page N ———" line before each page. Default true. |
reflow | boolean default false | Join the lines of each paragraph and mend words split by a hyphen. |
perPage | boolean default false | Also return each page's text separately. |
maxChars | integer default 200000 | Cut the inline text after this many characters (the file output is never cut). |
output | string | Write the text to this file (or folder ending in "/") instead of returning it inline. |
Example
{
"file": "article.pdf",
"reflow": true
}Example
{
"file": "book.pdf",
"pages": "1-20",
"format": "markdown",
"output": "book.md"
}pdf_watermarkWatermark PDF
Stamp a text or image watermark on PDF pages: centred or tiled across the page, with opacity, angle, size, colour and a page range. It reads upright on rotated pages. Text the standard PDF fonts cannot draw (Arabic, CJK…) is stamped as an image. Defaults match the website: "CONFIDENTIAL", Helvetica Bold 72 pt, #d64545, 25% opacity, 45°. Web version: https://s3eidat.github.io/pdf-watermark/
| Input | Type | Description |
|---|---|---|
file required | string | The PDF: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
text | string | Watermark text (default "CONFIDENTIAL"). Ignored when "image" is given. |
image | string | Image watermark instead of text: a local path or base64 (PNG, JPEG, WebP, SVG…). |
font | "HelveticaBold" | "Helvetica" | "TimesRomanBold" | "CourierBold" default "HelveticaBold" | Font for text. |
size | number default 72 | Text size in points. Default 72. |
color | string default "#d64545" | Colour as hex "#rrggbb". Default #d64545. |
scale | number default 40 | Image width as % of the page width. Default 40. |
opacity | number default 25 | Opacity in % (1-100). Default 25. |
angle | number default 45 | Rotation in degrees, counter-clockwise as shown. Default 45. |
mode | "center" | "tile" default "center" | "center": one stamp in the middle; "tile": repeated across the page. |
gap | number default 80 | Space between tiles in points (tile mode). Default 80. |
pages | string | Pages to stamp: 1-based list like "1-3, 5, 8-" ("5-" = to the end, "-3" = first three, "3-1" = reversed). Also "all", "odd", "even", "last". Empty = all pages. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example
{
"file": "roadmap.pdf",
"text": "DRAFT",
"opacity": 20
}Example
{
"file": "brochure.pdf",
"image": "logo.png",
"mode": "tile",
"scale": 15,
"angle": 0,
"opacity": 10
}Images
Convert, resize, crop, compress, watermark, EXIF, palettes, favicons, placeholders.
image_ascii_artImage to ASCII art
Turn an image into ASCII art: each character cell takes the average brightness of its area (cells are twice as tall as wide) and maps it onto a character ramp: standard " .:-=+*#%@", detailed (70 characters), blocks " ░▒▓█", simple, binary, or your own. Contrast, brightness and invert (for light text on dark backgrounds). Returns the text; format "png" also renders it to an image (optionally in the image's colours). Transparent areas count as white paper. Web version: https://s3eidat.github.io/ascii-art/
| Input | Type | Description |
|---|---|---|
image required | string | The image: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
columns | integer default 100 | Characters per line. Default 100. |
ramp | "standard" | "detailed" | "blocks" | "simple" | "binary" | "custom" default "standard" | Character set, light → dark. Default standard. |
customRamp | string default " .oO0@" | Characters for ramp "custom", from no ink to most ink (at least 2). |
contrast | number default 0 | -100 … 100. Default 0. |
brightness | number default 0 | -100 … 100. Default 0. |
invert | boolean default false | For light text on a dark background. Default false. |
format | "text" | "png" default "text" | text (default) or png (also writes <name>-ascii.png). |
color | boolean default false | PNG only: colour each character with the image colour. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
Example
{
"image": "/photos/cat.jpg",
"columns": 80,
"contrast": 20
}Example
{
"image": "/photos/logo.png",
"ramp": "blocks",
"format": "png",
"color": true
}image_ascii_bannerText to ASCII banner
Big banner letters from text, using the website's own bitmap fonts: block (█ 5×7), char (any fill character, e.g. #), shadow (█ with ░ shade), compact (half-block 5×7), small (█ 3×5), tiny (half-block 3×5). Letters A-Z, digits and common punctuation (unknown characters show as "?"); one banner per input line. Returns the text; format "png" also renders it to banner.png. Web version: https://s3eidat.github.io/ascii-art/
| Input | Type | Description |
|---|---|---|
text required | string | Text to render (case-insensitive). New lines make separate banners. |
style | "block" | "char" | "shadow" | "compact" | "small" | "tiny" default "block" | Letter style. Default block. |
fill | string default "#" | Fill character(s) for style "char". Default "#". |
format | "text" | "png" default "text" | text (default) or png (also writes banner.png). |
theme | "dark" | "light" default "dark" | PNG colours: dark (teal on near-black, default) or light. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
Example: A 7-line banner: "## ## ######" …
{
"text": "HI",
"style": "char",
"fill": "#"
}Result
{
"lines": 7
}image_compressCompress image
Make an image file smaller: re-encode at a quality (default 80) and optionally cap the longest side (maxSide), as JPEG, WebP, AVIF or PNG ("keep" = same format; GIF/BMP/TIFF become PNG). Or give targetBytes to find the highest quality that fits that size. With keepSmaller (default on) the original is kept when re-encoding would not make it smaller. Reports before/after sizes and % saved. Transparent areas become white in JPEG. Metadata (EXIF, GPS) is not copied. PNG is lossless (quality ignored). Web version: https://s3eidat.github.io/image-squeeze/
| Input | Type | Description |
|---|---|---|
image required | string | The image: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
format | "keep" | "jpeg" | "webp" | "avif" | "png" default "keep" | Output format. Default keep (same as the input). |
quality | integer default 80 | Quality 1-100 for JPEG / WebP / AVIF. Default 80 (website default). |
maxSide | integer | Scale down so the longest side is at most this many pixels (e.g. 1920). |
targetBytes | integer | Aim for a file of at most this many bytes: searches the highest quality that fits (lossy formats only; overrides quality). |
keepSmaller | boolean default true | Keep the original bytes when the result would be larger (same format and size only). Default true. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example
{
"image": "/photos/IMG_0042.jpg",
"quality": 75,
"maxSide": 1920
}Example: Highest WebP quality that fits 150 KB.
{
"image": "/site/hero.png",
"format": "webp",
"targetBytes": 150000
}image_convertConvert image format
Convert an image to PNG, JPEG, WebP, AVIF, GIF or TIFF. Reads JPEG, PNG, WebP, AVIF/HEIF, GIF (first frame), TIFF, SVG, BMP and ICO. Transparent areas are filled with `background` when writing JPEG (or always with `flatten`). EXIF rotation is applied. SVGs are rasterised at their own size (width/height or viewBox; 1024×1024 if neither), scripts never run. Images larger than 16384 px a side or 100 MP are scaled down to fit. Web version: https://s3eidat.github.io/image-convert/
| Input | Type | Description |
|---|---|---|
image required | string | The image: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
format | "png" | "jpeg" | "webp" | "avif" | "gif" | "tiff" default "png" | Output format. Default png (as on the website). |
quality | integer default 92 | Quality 1-100 for JPEG / WebP / AVIF (ignored for PNG). Default 92, same as the website. |
background | string default "#ffffff" | Colour used for transparent areas when writing JPEG or when flatten is on. Default #ffffff. |
flatten | boolean default false | Fill transparency with the background for every format, not only JPEG. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: Writes logo.jpg with transparency on white.
{
"image": "/photos/logo.png",
"format": "jpeg",
"quality": 90,
"background": "#ffffff"
}Example
{
"image": "/icons/icon.svg",
"format": "webp"
}image_cropCrop image
Crop an image to a pixel box (x, y, width, height) or to an aspect ratio (1:1, 4:5, 3:2, 16:9, 9:16, "W:H" or a number), taking the largest centred region (or aligned to an edge with `position`). Boxes are kept inside the image. Output JPEG/PNG/WebP/AVIF, name <name>-<W>x<H>.<ext>. Web version: https://s3eidat.github.io/image-resize/
| Input | Type | Description |
|---|---|---|
image required | string | The image: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
x | integer | Left edge of the crop box (pixels). Use with y, width, height. |
y | integer | Top edge of the crop box (pixels). |
width | integer | Width of the crop box (pixels). |
height | integer | Height of the crop box (pixels). |
ratio | string | number | Aspect ratio as "W:H" (e.g. "1:1", "4:5", "3:2", "16:9", "9:16"), a number (width/height), "orig" or "free". |
position | "center" | "top" | "bottom" | "left" | "right" | "top-left" | "top-right" | "bottom-left" | "bottom-right" default "center" | Where the ratio crop sits. Default center (the website default). |
format | "keep" | "jpeg" | "png" | "webp" | "avif" default "keep" | Output format. "keep" = same as the input when it is JPEG/PNG/WebP (else PNG). Default keep. |
quality | integer default 90 | Quality 1-100 for JPEG / WebP / AVIF (ignored for PNG). Default 90, same as the website. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: Largest centred square.
{
"image": "/photos/group.jpg",
"ratio": "1:1"
}Example
{
"image": "/photos/group.jpg",
"x": 100,
"y": 50,
"width": 800,
"height": 600
}image_exif_readRead photo metadata (EXIF)
Show the hidden metadata in a photo: camera make/model, lens, date taken, exposure, ISO, software, author/copyright, serial numbers, comments, PNG text chunks, and GPS coordinates (where the photo was taken). Lists every metadata block (EXIF, XMP, ICC, IPTC, embedded previews) with its size and flags privacy-sensitive fields. JPEG and PNG fully; WebP/AVIF/HEIC/TIFF EXIF via sharp. Web version: https://s3eidat.github.io/exif-cleaner/
| Input | Type | Description |
|---|---|---|
image required | string | The photo: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
Example: Camera Google Pixel 9, Date taken 2026:10:21 18:42:05, GPS 31.953900, 35.910600.
{
"image": "/photos/IMG_20261021_184205.jpg"
}image_exif_stripRemove photo metadata (EXIF)
Remove EXIF, GPS location, XMP, IPTC, comments, PNG text chunks and embedded previews from a photo before sharing it. JPEG and PNG are cleaned losslessly (image data copied byte for byte, like the website); by default the rotation is kept as a tiny orientation-only EXIF and the ICC colour profile is kept. applyOrientation re-encodes JPEGs with the rotation baked into the pixels. WebP/AVIF/HEIC/TIFF are re-encoded without metadata. Output name <name>-clean.<ext>. Web version: https://s3eidat.github.io/exif-cleaner/
| Input | Type | Description |
|---|---|---|
image required | string | The photo: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
keepOrientation | boolean default true | Keep only the Orientation tag so the photo still shows the right way up. Default true. |
keepIcc | boolean default true | Keep the ICC colour profile (no personal data; keeps colours right). Default true. |
applyOrientation | boolean default false | Instead of keeping the Orientation tag, rotate the pixels (re-encodes JPEG at `quality`; PNG is unaffected). Default false. |
quality | integer default 92 | JPEG/WebP/AVIF quality when re-encoding is needed. Default 92. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: Writes IMG_1234-clean.jpg: no GPS, camera or date; same pixels.
{
"image": "/photos/IMG_1234.jpg"
}Example
{
"image": "/photos/IMG_1234.jpg",
"applyOrientation": true
}image_favicon_setFavicon set generator
Make a complete favicon set from a letter/emoji/short text or from an image: favicon.ico (16, 32, 48 px), favicon-16x16.png, favicon-32x32.png, apple-touch-icon.png (180, square, solid), android-chrome-192x192.png and -512x512.png, site.webmanifest and head-snippet.html with the <link> tags. Rounded square with background colour (or transparent), corner radius and padding in %. Writes everything into one folder. Web version: https://s3eidat.github.io/favicon-forge/
| Input | Type | Description |
|---|---|---|
text | string default "S" | Letter(s) or emoji drawn on the icon (when no image is given). Default "S". |
image | string | Use this image (logo) instead of text: a local path or base64. Square, 512 px+ works best. |
weight | "400" | "500" | "600" | "700" | "800" | "900" default "900" | Font weight for text. Default 900. |
color | string default "#ffffff" | Text colour. Default #ffffff. |
background | string default "#0e7c86" | Background colour. Default #0e7c86. |
transparent | boolean default false | Transparent background (the Apple icon still gets white). Default false. |
radius | number default 22 | Corner radius in % of the size (50 = circle). Default 22. |
padding | number default 14 | Padding around the text/image in %. Default 14. |
fit | "contain" | "cover" default "contain" | How an image fills the padded square. Default contain. |
name | string default "My Website" | App name for site.webmanifest. Default "My Website". |
shortName | string default "Site" | Short name for site.webmanifest. Default "Site". |
output | string | Folder to write the files into. Default: a new "favicons" folder in the output folder. |
Example
{
"text": "S3",
"background": "#0e7c86",
"radius": 24,
"padding": 16,
"name": "S3eidat Tools",
"shortName": "S3eidat"
}Result
{
"folder": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-HmqiFx\\favicons\\",
"files": [
{
"name": "favicon.ico",
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-HmqiFx\\favicons\\favicon.ico",
"bytes": 4462
},
{
"name": "favicon-16x16.png",
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-HmqiFx\\favicons\\favicon-16x16.png",
"bytes": 688
},
{
"name": "favicon-32x32.png",
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-HmqiFx\\favicons\\favicon-32x32.png",
"bytes": 1394
},
{
"name": "apple-touch-icon.png",
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-HmqiFx\\favicons\\apple-touch-icon.png",
"bytes": 6647
},
{
"name": "android-chrome-192x192.png",
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-HmqiFx\\favicons\\android-chrome-192x192.png",
"bytes": 9738
},
{
"name": "android-chrome-512x512.png",
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-HmqiFx\\favicons\\android-chrome-512x512.png",
"bytes": 20070
},
{
"name": "site.webmanifest",
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-HmqiFx\\favicons\\site.webmanifest",
"bytes": 380
},
{
"name": "head-snippet.html",
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-HmqiFx\\favicons\\head-snippet.html",
"bytes": 368
}
],
"snippet": "<link rel=\"icon\" href=\"/favicon.ico\" sizes=\"48x48\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/favicon-32x32.png\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/favicon-16x16.png\">\n<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/apple-touch-icon.png\">\n<link rel=\"manifest\" href=\"/site.webmanifest\">\n<meta name=\"theme-color\" content=\"#0e7c86\">"
}Example
{
"image": "/brand/logo.png",
"transparent": true,
"radius": 0,
"output": "/site/public/"
}image_from_base64Base64 / data URI to image file
Decode Base64 back into a file: accepts a data URI, a CSS url("data:…") rule, an <img src="data:…"> tag, URL-encoded SVG data URIs, or raw Base64 (standard or URL-safe, line breaks allowed). Detects the real type from the bytes, warns when it differs from the declared one, and writes decoded.<ext>. Give the text inline or as a path to a text file. Web version: https://s3eidat.github.io/image-to-base64/
| Input | Type | Description |
|---|---|---|
text | string | The data URI / CSS / <img> tag / raw Base64. |
path | string | Or: a text file containing it. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
Example: Writes decoded.png (1×1).
{
"text": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
}Result
{
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-BKoKKG\\decoded.png",
"bytes": 70,
"mimeType": "image/png",
"declaredMimeType": "image/png",
"detectedMimeType": "image/png",
"isImage": true,
"width": 1,
"height": 1,
"status": "Valid image"
}image_paletteColour palette from image
Extract the main colours of an image with their share of the picture: k-means (default, deterministic) or median cut, 1-16 colours, sorted by share. Transparent pixels are ignored. Returns hex + rgb + % per colour, CSS custom properties (:root { --color-1 … }) or JSON, and optionally writes the website's swatch strip as palette.png. Same algorithm and sampling as the website, so the colours match. Web version: https://s3eidat.github.io/palette-from-image/
| Input | Type | Description |
|---|---|---|
image required | string | The image: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
count | integer default 6 | Number of colours. Default 6. |
method | "kmeans" | "median" default "kmeans" | kmeans (default) or median (median cut). |
format | "css" | "json" default "css" | Export text format. Default css. |
swatchPng | boolean default false | Also write palette.png (160×200 swatch per colour with its hex code). |
output | string | Where to write palette.png (file path or folder ending in "/"). Implies swatchPng. |
Example: colors: [{ hex: "#1f2f6e", percent: "31.2%" }, …]
{
"image": "/photos/sunset.jpg",
"count": 5
}image_placeholderPlaceholder image
Make a placeholder image of any size (up to 8000 px a side): solid background with centred text (default "W × H", "\n" for line breaks), auto-fitted font size or a fixed one, PNG / JPEG / WebP / SVG. Size presets for web, social media, IAB ads and devices. Optionally returns a data URI / <img> tag for inlining. Text uses Inter when installed, else a system sans-serif. Web version: https://s3eidat.github.io/placeholder-image/
| Input | Type | Description |
|---|---|---|
width | integer default 1200 | Width in pixels. Default 1200. |
height | integer default 630 | Height in pixels. Default 630. |
preset | "open-graph-link-preview" | "hero-16-9-full-hd" | "hd-16-9" | "blog-image-4-3" | "thumbnail-3-2" | "avatar" | "instagram-square" | "instagram-portrait-4-5" | "story-reel-9-16" | "x-twitter-header" | "linkedin-banner" | "youtube-thumbnail" | "medium-rectangle" | "leaderboard" | "wide-skyscraper" | "mobile-banner" | "half-page" | "billboard" | "iphone-15-screen" | "desktop-1440" | "4k-uhd" | Size preset (overrides width/height): open-graph-link-preview 1200×630, hero-16-9-full-hd 1920×1080, hd-16-9 1280×720, blog-image-4-3 800×600, thumbnail-3-2 600×400, avatar 256×256, instagram-square 1080×1080, instagram-portrait-4-5 1080×1350, story-reel-9-16 1080×1920, x-twitter-header 1500×500, linkedin-banner 1584×396, youtube-thumbnail 1280×720, medium-rectangle 300×250, leaderboard 728×90, wide-skyscraper 160×600, mobile-banner 320×50, half-page 300×600, billboard 970×250, iphone-15-screen 1179×2556, desktop-1440 1440×900, 4k-uhd 3840×2160. |
background | string default "#1f2937" | Background colour (#rgb or #rrggbb). Default #1f2937. |
color | string default "#9ca3af" | Text colour (#rgb or #rrggbb). Default #9ca3af. |
text | string default "" | Text to show. Empty = "W × H". Use "\n" (backslash n) or a real newline for a line break. |
fontSize | number default 0 | Font size in px; 0 = auto-fit (default). |
fontWeight | "400" | "500" | "600" | "700" | "800" | "900" default "600" | Font weight. Default 600. |
format | "png" | "jpeg" | "webp" | "svg" default "png" | Output format. Default png. |
dataUri | boolean default false | Also return the image as a data URI and an <img> tag (for small images). |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: placeholder-1200x630.png with "1200 × 630".
{
"width": 1200,
"height": 630
}Result
{
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-yPrhd0\\placeholder-1200x630.png",
"bytes": 29305,
"mimeType": "image/png",
"width": 1200,
"height": 630,
"format": "png",
"aspectRatio": "40:21",
"megapixels": "0.76",
"fontSize": 133
}Example
{
"preset": "leaderboard",
"background": "#0e9f9a",
"color": "#e6fffd",
"text": "Ad space",
"format": "svg"
}Result
{
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-FqID82\\placeholder-728x90.svg",
"bytes": 421,
"mimeType": "image/svg+xml",
"width": 728,
"height": 90,
"format": "svg",
"aspectRatio": "364:45",
"megapixels": "0.07",
"fontSize": 31
}image_resizeResize image
Resize an image by pixels or percent, keeping the aspect ratio. Give width or height (the other side follows), or both: fit "cover" (default, as on the website) centre-crops to that ratio first so nothing is stretched, "contain" fits inside the box, "fill" stretches. Optional crop ratio (1:1, 4:5, 3:2, 16:9, 9:16, orig) or crop box before resizing, social-media presets, output JPEG/PNG/WebP/AVIF. Up to 16384 px a side. Output name: <name>-<W>x<H>.<ext>. Web version: https://s3eidat.github.io/image-resize/
| Input | Type | Description |
|---|---|---|
image required | string | The image: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
width | integer | Target width in pixels. |
height | integer | Target height in pixels. |
percent | number | Scale by percent instead (e.g. 50 halves both sides, 200 doubles). |
preset | "instagram-post" | "instagram-portrait" | "story" | "youtube-thumbnail" | "x-header" | "facebook-cover" | "linkedin-banner" | "full-hd" | "passport-35x45" | "us-passport-2x2" | Exact output size preset: instagram-post 1080×1080, instagram-portrait 1080×1350, story 1080×1920, youtube-thumbnail 1280×720, x-header 1500×500, facebook-cover 851×315, linkedin-banner 1584×396, full-hd 1920×1080, passport-35x45 413×531, us-passport-2x2 600×600. |
fit | "cover" | "contain" | "fill" default "cover" | When both width and height are set: cover (crop to fill, default), contain (fit inside), fill (stretch). |
ratio | string | number | Aspect ratio as "W:H" (e.g. "1:1", "4:5", "3:2", "16:9", "9:16"), a number (width/height), "orig" or "free". |
crop | object | Crop box (x, y, width, height in pixels) applied before resizing; overrides ratio. |
format | "keep" | "jpeg" | "png" | "webp" | "avif" default "keep" | Output format. "keep" = same as the input when it is JPEG/PNG/WebP (else PNG). Default keep. |
quality | integer default 90 | Quality 1-100 for JPEG / WebP / AVIF (ignored for PNG). Default 90, same as the website. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: Keeps the aspect ratio: 1600×900 → 1080×608.
{
"image": "/photos/beach.jpg",
"width": 1080
}Example: Centre-crops to 1:1 and writes beach-1080x1080.jpg.
{
"image": "/photos/beach.jpg",
"preset": "instagram-post"
}Example
{
"image": "/photos/beach.jpg",
"percent": 50,
"format": "webp"
}image_rotateRotate / flip image
Rotate an image clockwise by 90, 180, 270 or any angle (the canvas grows to fit; new corners get `background`), and/or flip it horizontally (mirror) or vertically. Flips apply after the rotation, as seen on screen. EXIF orientation is applied first (autoOrient, default on), so with angle 0 this simply "fixes" sideways phone photos. Output JPEG/PNG/WebP/AVIF ("keep" = same as input), name <name>-rotated.<ext>. Web version: https://s3eidat.github.io/photo-filters/
| Input | Type | Description |
|---|---|---|
image required | string | The image: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
angle | number default 90 | Clockwise rotation in degrees (negative = counter-clockwise). Default 90. |
flipHorizontal | boolean default false | Mirror left-right (after rotating). |
flipVertical | boolean default false | Mirror top-bottom (after rotating). |
autoOrient | boolean default true | Apply the EXIF Orientation tag first (what browsers show). Default true. |
background | string default "#00000000" | Fill for the corners uncovered by a non-right-angle rotation. Default transparent (white in JPEG). |
format | "keep" | "jpeg" | "png" | "webp" | "avif" default "keep" | Output format. Default keep (JPEG/PNG/WebP stay, others become PNG). |
quality | integer default 92 | Quality 1-100 for JPEG / WebP / AVIF (ignored for PNG). Default 92, same as the website. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example
{
"image": "/photos/scan.jpg",
"angle": 90
}Example: Un-mirror a selfie.
{
"image": "/photos/selfie.jpg",
"angle": 0,
"flipHorizontal": true
}Example: Bake the EXIF rotation into the pixels.
{
"image": "/photos/IMG_1234.jpg",
"angle": 0
}image_svg_to_pngSVG to PNG
Rasterise an SVG to a crisp PNG: scale (1×, 2×, 3×, 4×… default 2×), a target width or height (aspect kept), or an exact size (stretched). Units (px, pt, mm, cm, in) and viewBox-only SVGs are understood; transparent background or a solid colour. Scripts, event handlers and external references are removed first. Name <name>@2x.png. Web version: https://s3eidat.github.io/svg-to-png/
| Input | Type | Description |
|---|---|---|
svg | string | The SVG: a local path or base64 / data URI. |
svgText | string | Or: the SVG code itself. |
mode | "scale" | "width" | "height" | "exact" default "scale" | How to size the PNG. Default scale. |
scale | number default 2 | Scale factor for mode "scale". Default 2. |
width | integer | Width in px for modes width / exact. |
height | integer | Height in px for modes height / exact. |
transparent | boolean default true | Keep the background transparent. Default true. |
background | string default "#ffffff" | Background colour when transparent is false. Default #ffffff. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example: Writes logo@3x.png.
{
"svg": "/icons/logo.svg",
"scale": 3
}Example: 200×100 PNG.
{
"svgText": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 50\"/>",
"mode": "width",
"width": 200
}Result
{
"path": "C:\\Users\\User\\AppData\\Local\\Temp\\s3eidat-docs-sMIPxv\\image.png",
"bytes": 179,
"mimeType": "image/png",
"width": 200,
"height": 100,
"svgWidth": 100,
"svgHeight": 50
}image_to_base64Image to Base64 / data URI
Encode an image (or any file) as Base64: a data URI, bare Base64, a CSS background-image rule, an HTML <img> tag (with width/height), Markdown, or for SVG a URL-encoded data URI (usually ~30% smaller). Detects the type from the bytes and warns when the result is too big to inline (over 10 KB: slows pages; over 1 MB: use a normal file). Results longer than maxChars are written to a .txt file instead of being returned. Web version: https://s3eidat.github.io/image-to-base64/
| Input | Type | Description |
|---|---|---|
image required | string | The image: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
as | "dataUri" | "base64" | "css" | "html" | "markdown" | "svgUri" default "dataUri" | What to return: dataUri (default), base64, css, html, markdown, or svgUri (SVG only). |
mimeType | string | Override the detected MIME type (e.g. image/svg+xml). |
maxChars | integer default 200000 | Longest text returned inline; longer results go to a file. Default 200000. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
Example: background-image: url("data:image/png;base64,…");
{
"image": "/site/icons/logo.png",
"as": "css"
}Example
{
"image": "/site/icons/arrow.svg",
"as": "svgUri"
}image_watermarkWatermark image
Add a text or logo watermark to a photo. Size is a % of the photo width, margin a % of the shorter side, so the result looks the same on any resolution. One of 9 positions or tiled across the whole image (brick pattern), with opacity, rotation, colour, weight and a soft shadow for text. Logo: any image (PNG with transparency works best). Output keeps the input format (JPEG/PNG/WebP) or as chosen; name <name>-watermarked.<ext>. Text uses the Inter font when installed, else a system sans-serif. Web version: https://s3eidat.github.io/watermark/
| Input | Type | Description |
|---|---|---|
image required | string | The photo: a local file path (absolute, or relative to the server's --root) or base64 data (raw or a data: URI). |
text | string default "© Your Name" | Watermark text (ignored when a logo is given). Default "© Your Name". |
logo | string | Use this image as the watermark instead of text: a local path or base64. |
color | string default "#ffffff" | Text colour. Default #ffffff. |
weight | "400" | "500" | "600" | "700" | "800" | "900" default "700" | Font weight. Default 700. |
shadow | boolean default true | Soft drop shadow behind text. Default true. |
position | "top-left" | "top" | "top-right" | "left" | "center" | "right" | "bottom-left" | "bottom" | "bottom-right" default "bottom-right" | Where the watermark sits (ignored when tiled). Default bottom-right. |
tiled | boolean default false | Repeat the watermark across the whole photo. |
opacity | number default 60 | Opacity in %. Default 60. |
size | number default 28 | Watermark width as % of the photo width. Default 28. |
rotation | number default 0 | Rotation in degrees (e.g. -30 for a diagonal tile). Default 0. |
margin | number default 4 | Margin from the edge in % of the shorter side; spacing between tiles when tiled. Default 4. |
format | "keep" | "jpeg" | "png" | "webp" default "keep" | Output format. Default keep. |
quality | integer default 92 | Quality 1-100 for JPEG / WebP / AVIF (ignored for PNG). Default 92, same as the website. |
output | string | Where to write the result: a file path, or a folder ending in "/". Default: the server output folder (a temp folder unless --out-dir is set). |
returnBase64 | boolean default false | Also return the output as base64 in the result (only for small files). Default false. |
Example
{
"image": "/photos/shoot-01.jpg",
"text": "© Studio Lina",
"position": "bottom-right",
"opacity": 60
}Example
{
"image": "/photos/proof.jpg",
"text": "PROOF",
"tiled": true,
"rotation": -25,
"opacity": 35,
"size": 26,
"margin": 3
}Example
{
"image": "/photos/product.png",
"logo": "/brand/logo.png",
"position": "top-left",
"size": 20
}Text
Counting, case, slugs, cleaning, diffs, readability, Arabic tools, numbers to words, citations.
text_arabicArabic text tools
Arabic text utilities. mode "clean": remove tashkeel (harakat and Quranic marks, optionally keeping shadda), remove tatweel (kashida), normalise letters (alef with hamza/madda/wasla → bare alef; alef maqsura and Farsi ya → ya; ta marbuta → ha; hamza on waw/ya → waw/ya), switch Latin , ; ? to Arabic punctuation, and convert digits (Arabic-Indic ↔ Western). mode "arabizi": turn Arabizi / Franco-Arabic chat text (mar7aba, 3arabi, 5ala9, el bait) into Arabic script. Returns the result with letter/word/character counts. Give "text" or a text file "path". Web version: https://s3eidat.github.io/arabic-tools/
| Input | Type | Description |
|---|---|---|
text | string | The text to transform. |
path | string | Or: a path to a UTF-8 text file. |
mode | "clean" | "arabizi" default "clean" | "clean" = clean & normalise Arabic text (default); "arabizi" = Arabizi (Latin letters + numbers) → Arabic script. |
removeTashkeel | boolean default true | clean: remove tashkeel / harakat (default true). |
keepShadda | boolean default false | clean: when removing tashkeel, keep the shadda. |
removeTatweel | boolean default true | clean: remove tatweel / kashida (default true). |
normalizeAlef | boolean default false | clean: alef with hamza above/below, madda or wasla → bare alef. |
normalizeYa | boolean default false | clean: alef maqsura and Farsi ya → Arabic ya. |
taMarbutaToHa | boolean default false | clean: ta marbuta → ha. |
normalizeHamza | boolean default false | clean: hamza on waw → waw, hamza on ya → ya. |
arabicPunctuation | boolean default false | clean: Latin comma, semicolon and question mark → Arabic ones. |
digits | "keep" | "western" | "arabic" default "keep" | clean: keep digits, convert Arabic-Indic/Persian digits to 0-9 ("western"), or 0-9 to Arabic-Indic ("arabic"). |
output | string | Optional: write the result to this file path (or folder ending in "/") instead of returning it. |
Example
{
"mode": "arabizi",
"text": "mar7aba, kifak?"
}Result
{
"text": "مرحبا، كيفك؟",
"arabicLetters": 9,
"words": 2,
"characters": 12
}Example
{
"text": "2026",
"digits": "arabic"
}Result
{
"text": "٢٠٢٦",
"arabicLetters": 0,
"words": 1,
"characters": 4,
"marksRemoved": 0
}text_caseCase convert
Convert text case: upper, lower, title (smart: keeps small words lower and iPhone/NASA as typed), sentence, camel, pascal, snake, kebab, constant, alternate, inverse. Works line by line and handles Unicode (Arabic, accents, ß). Web version: https://s3eidat.github.io/case-convert/
| Input | Type | Description |
|---|---|---|
text required | string | Text to convert. |
mode required | "upper" | "lower" | "title" | "sentence" | "camel" | "pascal" | "snake" | "kebab" | "constant" | "alternate" | "inverse" | Target case. |
Example
{
"text": "a tale OF two cities",
"mode": "title"
}Result
{
"result": "A Tale of Two Cities"
}Example
{
"text": "XMLParser handler",
"mode": "snake"
}Result
{
"result": "xml_parser_handler"
}text_citationCitation generator
Format references from structured fields in APA 7, MLA 9, Chicago author-date (17th), Harvard (Cite Them Right) or IEEE, for books, book chapters, journal articles, web pages, newspaper/magazine articles, videos and reports. Handles author-count rules (et al.), initials, organisations as authors, editions, page ranges (MLA 127-53), DOIs, URLs and access dates, and title case for MLA/Chicago/IEEE. Returns each citation as plain text and HTML (italics as <i>), the in-text citation, missing-field hints, and the whole list as a bibliography sorted for the style (numbered for IEEE). Web version: https://s3eidat.github.io/citation-gen/
| Input | Type | Description |
|---|---|---|
style required | "apa" | "mla" | "chicago" | "harvard" | "ieee" | Citation style: apa, mla, chicago, harvard or ieee. |
sources required | object[] | One or more sources. |
autoCase | boolean default true | Apply title case where the style wants it (MLA, Chicago, IEEE book titles). Default true. |
Example: Abelson, H., & Sussman, G. J. (1996). Structure and interpretation of computer programs (2nd ed.). MIT Press.
{
"style": "apa",
"sources": [
{
"type": "book",
"authors": [
{
"first": "Harold",
"last": "Abelson"
},
{
"first": "Gerald Jay",
"last": "Sussman"
}
],
"title": "Structure and interpretation of computer programs",
"edition": "2",
"year": "1996",
"publisher": "MIT Press",
"place": "Cambridge, MA, USA"
}
]
}Result
{
"style": "APA 7",
"citations": [
{
"text": "Abelson, H., & Sussman, G. J. (1996). Structure and interpretation of computer programs (2nd ed.). MIT Press.",
"html": "Abelson, H., & Sussman, G. J. (1996). <i>Structure and interpretation of computer programs</i> (2nd ed.). MIT Press.",
"inText": "(Abelson & Sussman, 1996)",
"missing": []
}
],
"bibliographyTitle": "References",
"bibliography": "Abelson, H., & Sussman, G. J. (1996). Structure and interpretation of computer programs (2nd ed.). MIT Press."
}text_cleanText cleaner
Clean up text line by line with a fixed pipeline (same order as the website): strip HTML tags and decode entities → remove emojis → trim each line → collapse repeated spaces → remove empty lines → remove duplicate lines (optionally ignoring case) → sort (A–Z, Z–A, natural, by length) → reverse → shuffle (seedable) → add line numbers. Returns the cleaned text plus counts, or writes it to a file when "output" is given. Give "text" or a text file "path". Web version: https://s3eidat.github.io/text-cleaner/
| Input | Type | Description |
|---|---|---|
text | string | The text to clean. |
path | string | Or: a path to a UTF-8 text file. |
stripHtml | boolean default false | Strip HTML tags (drops script/style/comments, block ends become line breaks) and decode entities (default false). |
removeEmoji | boolean default false | Remove emojis (©, ® and ™ are kept) (default false). |
trim | boolean default true | Trim spaces at the start and end of each line (default true). |
collapseSpaces | boolean default true | Collapse runs of spaces/tabs into one space (default true). |
removeEmptyLines | boolean default true | Remove empty (whitespace-only) lines (default true). |
removeDuplicates | boolean default false | Remove duplicate lines, keeping the first (default false). |
ignoreCase | boolean default false | When removing duplicates, treat lines that differ only in case as duplicates (default false). |
sort | "none" | "az" | "za" | "natural" | "length" default "none" | Sort lines: none (default), az, za, natural (item 2 before item 10), length (shortest first). |
reverse | boolean default false | Reverse the line order (default false). |
shuffle | boolean default false | Shuffle the lines (default false). |
seed | integer | Seed for a reproducible shuffle (default: random). |
numberLines | boolean default false | Prefix each line with its number ("1. ", padded) (default false). |
output | string | Optional: write the cleaned text to this file path (or folder ending in "/") instead of returning it. |
Example
{
"text": "item 10\nitem 2\nitem 2\n\nitem 1",
"removeDuplicates": true,
"sort": "natural"
}Result
{
"text": "item 1\nitem 2\nitem 10",
"linesIn": 5,
"linesOut": 3,
"duplicatesRemoved": 1,
"emptyLinesRemoved": 1,
"charactersOut": 21
}text_diffDiff two texts
Compare two texts line by line (Myers diff) and return a unified diff (3 lines of context, like `diff -u`), counts of added/removed/unchanged lines, and change blocks where each removed line is paired with the added line that replaced it and the changed words are marked [-old-] / {+new+}. Can ignore whitespace and case. Works with any language (Arabic included). Up to 50,000 lines per side. Web version: https://s3eidat.github.io/diff-view/
| Input | Type | Description |
|---|---|---|
original | string | The original text ("before"). |
originalPath | string | Or: path to the original text file. |
changed | string | The changed text ("after"). |
changedPath | string | Or: path to the changed text file. |
ignoreWhitespace | boolean default false | Treat lines that differ only in spacing as equal. |
ignoreCase | boolean default false | Treat lines that differ only in letter case as equal. |
wordDiff | boolean default true | Mark the changed words inside paired lines (default true). |
nameA | string | Label for the "---" header (default "original"). |
nameB | string | Label for the "+++" header (default "changed"). |
Example
{
"original": "one\ntwo\nthree",
"changed": "zero\none\nthree"
}Result
{
"identical": false,
"added": 1,
"removed": 1,
"unchanged": 2,
"unified": "--- original\n+++ changed\n@@ -1,3 +1,3 @@\n+zero\n one\n-two\n three\n",
"changes": [
{
"removed": [],
"added": [
{
"line": 1,
"text": "zero"
}
]
},
{
"removed": [
{
"line": 2,
"text": "two"
}
],
"added": []
}
]
}Example: changes[0]: removed marked "the [-quick-] fox", added marked "the {+slow+} fox"
{
"original": "the quick fox",
"changed": "the slow fox"
}Result
{
"identical": false,
"added": 1,
"removed": 1,
"unchanged": 0,
"unified": "--- original\n+++ changed\n@@ -1 +1 @@\n-the quick fox\n+the slow fox\n",
"changes": [
{
"removed": [
{
"line": 1,
"text": "the quick fox",
"marked": "the [-quick-] fox"
}
],
"added": [
{
"line": 1,
"text": "the slow fox",
"marked": "the {+slow+} fox"
}
]
}
]
}text_escapeEscape / unescape text
Escape or unescape a string for a target: JSON (string body), JavaScript (incl. template literals), HTML, XML, URL (encodeURIComponent, optional form +), SQL (doubled quotes, optional MySQL backslashes and wrapping quotes), CSV field (RFC 4180; comma, semicolon or tab), regex, POSIX shell single quotes, C/C++, Java/C#, and Unicode escapes (\uXXXX, \u{X}, \UXXXXXXXX, &#xX;, U+XXXX). Options per target as on the website. Set "allTargets" to get the escaped form for every target at once. Web version: https://s3eidat.github.io/text-escape/
| Input | Type | Description |
|---|---|---|
text required | string | The text to escape, or the escaped text to unescape. |
target required | "json" | "js" | "html" | "xml" | "url" | "sql" | "csv" | "regex" | "shell" | "c" | "java" | "unicode" | Format: json, js, html, xml, url, sql, csv, regex, shell, c, java, unicode. |
direction | "escape" | "unescape" default "escape" | escape (default) or unescape. |
ascii | boolean default false | json/js/html/c/java: also escape non-ASCII characters (c: as UTF-8 octal). |
named | boolean default false | html (with ascii): prefer named entities such as ©. |
form | boolean default false | url: form style, + for spaces. |
wrap | boolean default false | sql: wrap in single quotes (unescape: strip them). |
mysql | boolean default false | sql: escape backslashes too (MySQL). |
alwaysQuote | boolean default false | csv: always quote the field. |
delimiter | "," | ";" | "\t" default "," | csv: field delimiter (comma, semicolon or tab). |
unicodeFormat | "u4" | "ubrace" | "u8" | "html" | "uplus" default "u4" | unicode: u4 = \uXXXX (JS, JSON, Java), ubrace = \u{X} (ES6, Rust, Swift), u8 = \UXXXXXXXX (Python, C), html = &#xX;, uplus = U+XXXX. |
every | boolean default false | unicode: escape every character, not only non-ASCII. |
allTargets | boolean default false | escape only: also return the text escaped for every target. |
Example
{
"text": "O'Brien",
"target": "sql",
"wrap": true
}Result
{
"result": "'O''Brien'",
"note": "Standard SQL doubles single quotes. Prefer parameterised queries over escaping.",
"inputCharacters": 7,
"outputCharacters": 10
}Example
{
"text": "a%20b%26c",
"target": "url",
"direction": "unescape"
}Result
{
"result": "a b&c",
"note": "encodeURIComponent: for one query value or path segment.",
"inputCharacters": 9,
"outputCharacters": 5
}text_fancyFancy text (Unicode styles)
Restyle text with Unicode look-alike characters for bios and posts (28 styles): Bold, Italic, Bold italic, Script, Bold script, Fraktur, Bold fraktur, Double-struck, Sans-serif, Sans bold, Sans italic, Sans bold italic, Monospace, Circled, Circled dark, Squared, Squared dark, Parenthesized, Fullwidth, Small caps, Superscript, Upside down, Strikethrough, Underline, Double underline, Slashed, Overline, Wide spaced. Only Latin letters and digits change (other scripts such as Arabic and emoji pass through); some styles cover only capitals or only some symbols. Give one "style", or none to get every style. Up to 20,000 characters. Web version: https://s3eidat.github.io/fancy-text/
| Input | Type | Description |
|---|---|---|
text required | string | The text to restyle. |
style | "Bold" | "Italic" | "Bold italic" | "Script" | "Bold script" | "Fraktur" | "Bold fraktur" | "Double-struck" | "Sans-serif" | "Sans bold" | "Sans italic" | "Sans bold italic" | "Monospace" | "Circled" | "Circled dark" | "Squared" | "Squared dark" | "Parenthesized" | "Fullwidth" | "Small caps" | "Superscript" | "Upside down" | "Strikethrough" | "Underline" | "Double underline" | "Slashed" | "Overline" | "Wide spaced" | One style name (exact, e.g. "Bold", "Script", "Upside down"). Omit to get all styles. |
Example
{
"text": "Hello 2026",
"style": "Bold"
}Result
{
"results": [
{
"style": "Bold",
"text": "𝐇𝐞𝐥𝐥𝐨 𝟐𝟎𝟐𝟔"
}
]
}Example: Returns all 28 styles.
{
"text": "Stay curious"
}Result
{
"results": [
{
"style": "Bold",
"text": "𝐒𝐭𝐚𝐲 𝐜𝐮𝐫𝐢𝐨𝐮𝐬"
},
{
"style": "Italic",
"text": "𝑆𝑡𝑎𝑦 𝑐𝑢𝑟𝑖𝑜𝑢𝑠"
},
{
"style": "Bold italic",
"text": "𝑺𝒕𝒂𝒚 𝒄𝒖𝒓𝒊𝒐𝒖𝒔"
},
{
"style": "Script",
"text": "𝒮𝓉𝒶𝓎 𝒸𝓊𝓇𝒾ℴ𝓊𝓈"
},
{
"style": "Bold script",
"text": "𝓢𝓽𝓪𝔂 𝓬𝓾𝓻𝓲𝓸𝓾𝓼"
},
{
"style": "Fraktur",
"text": "𝔖𝔱𝔞𝔶 𝔠𝔲𝔯𝔦𝔬𝔲𝔰"
},
{
"style": "Bold fraktur",
"text": "𝕾𝖙𝖆𝖞 𝖈𝖚𝖗𝖎𝖔𝖚𝖘"
},
{
"style": "Double-struck",
"text": "𝕊𝕥𝕒𝕪 𝕔𝕦𝕣𝕚𝕠𝕦𝕤"
},
{
"style": "Sans-serif",
"text": "𝖲𝗍𝖺𝗒 𝖼𝗎𝗋𝗂𝗈𝗎𝗌"
},
{
"style": "Sans bold",
"text": "𝗦𝘁𝗮𝘆 𝗰𝘂𝗿𝗶𝗼𝘂𝘀"
},
{
"style": "Sans italic",
"text": "𝘚𝘵𝘢𝘺 𝘤𝘶𝘳𝘪𝘰𝘶𝘴"
},
{
"style": "Sans bold italic",
"text": "𝙎𝙩𝙖𝙮 𝙘𝙪𝙧𝙞𝙤𝙪𝙨"
},
{
"style": "Monospace",
"text": "𝚂𝚝𝚊𝚢 𝚌𝚞𝚛𝚒𝚘𝚞𝚜"
},
{
"style": "Circled",
"text": "Ⓢⓣⓐⓨ ⓒⓤⓡⓘⓞⓤⓢ"
},
{
"style": "Circled dark",
"text": "🅢🅣🅐🅨 🅒🅤🅡🅘🅞🅤🅢"
},
{
"style": "Squared",
"text": "🅂🅃🄰🅈 🄲🅄🅁🄸🄾🅄🅂"
},
{
"style": "Squared dark",
"text": "🆂🆃🅰🆈 🅲🆄🆁🅸🅾🆄🆂"
},
{
"style": "Parenthesized",
"text": "🄢⒯⒜⒴ ⒞⒰⒭⒤⒪⒰⒮"
},
{
"style": "Fullwidth",
"text": "Stay curious"
},
{
"style": "Small caps",
"text": "ꜱᴛᴀʏ ᴄᴜʀɪᴏᴜꜱ"
},
{
"style": "Superscript",
"text": "Sᵗᵃʸ ᶜᵘʳⁱᵒᵘˢ"
},
{
"style": "Upside down",
"text": "snoᴉɹnɔ ʎɐʇS"
},
{
"style": "Strikethrough",
"text": "S̶t̶a̶y̶ ̶c̶u̶r̶i̶o̶u̶s̶"
},
{
"style": "Underline",
"text": "S̲t̲a̲y̲ ̲c̲u̲r̲i̲o̲u̲s̲"
},
{
"style": "Double underline",
"text": "S̳t̳a̳y̳ ̳c̳u̳r̳i̳o̳u̳s̳"
},
{
"style": "Slashed",
"text": "S̸t̸a̸y̸ ̸c̸u̸r̸i̸o̸u̸s̸"
},
{
"style": "Overline",
"text": "S̅t̅a̅y̅ ̅c̅u̅r̅i̅o̅u̅s̅"
},
{
"style": "Wide spaced",
"text": "S t a y c u r i o u s"
}
]
}text_layout_fixKeyboard layout fixer (EN ⇄ AR)
Fix text typed with the wrong keyboard layout between US English (QWERTY) and Arabic (101): "hgsghl ugd;l" becomes the Arabic greeting, and Arabic gibberish typed on English keys becomes "hello". Direction "auto" detects it; in mixed text only the words that look mistyped are converted (using small English/Arabic letter-pair models), so words that are already right stay as they are. Handles the shift layer (harakat, hamza forms), lam-alef keys and Caps Lock (all-caps Latin input is treated as lowercase). Web version: https://s3eidat.github.io/layout-fixer/
| Input | Type | Description |
|---|---|---|
text | string | The mistyped text. |
path | string | Or: a path to a UTF-8 text file. |
direction | "auto" | "ar" | "en" default "auto" | "auto" (default) detects; "ar" = typed on English keys, convert to Arabic; "en" = typed on Arabic keys, convert to English. |
capsLock | boolean default false | Caps Lock was on: treat capital Latin letters as lowercase (detected automatically when all letters are capitals). |
Example
{
"text": ";dt phg;?"
}Result
{
"text": "كيف حالك؟",
"direction": "ar",
"wordsChanged": 2,
"capsLockIgnored": false
}Example: Mixed text: only the mistyped Arabic-looking word becomes "hello".
{
"text": "Hi, ok اثممخ"
}Result
{
"text": "Hi, ok hello",
"direction": "mixed",
"wordsChanged": 1,
"capsLockIgnored": false
}text_loremLorem ipsum generator
Generate placeholder text: classic Lorem ipsum, readable English filler, or Arabic filler. Choose paragraphs (max 100), sentences (max 500) or words (max 10000); optionally start with the classic opener and wrap paragraphs in <p> tags. Give a seed for repeatable output (the same seed gives the same text). Writes a .txt/.html file instead when "output" is given. Web version: https://s3eidat.github.io/lorem-gen/
| Input | Type | Description |
|---|---|---|
style | "lorem" | "english" | "arabic" default "lorem" | Word list: lorem (Latin), english, or arabic. |
unit | "paragraphs" | "sentences" | "words" default "paragraphs" | What "count" counts. |
count | integer default 3 | How many paragraphs / sentences / words (clamped to the unit limit). |
opener | boolean default true | Start with the classic opening line ("Lorem ipsum dolor sit amet…", "The quick brown fox…", or the Arabic one). Default true. |
html | boolean default false | Wrap each paragraph in <p>…</p>. |
seed | integer | Seed for repeatable output (default: random). |
output | string | Optional: write the text to this file path (or folder ending in "/") instead of returning it. |
Example: 25 words starting "Lorem ipsum dolor sit amet…"
{
"unit": "words",
"count": 25,
"seed": 42
}Example
{
"style": "arabic",
"unit": "paragraphs",
"count": 2
}text_morseMorse code translator
Translate text to International Morse code and back. Encoding: letters separated by spaces, words by " / "; accents are folded (é → E) and characters without a code are skipped and counted. Decoding accepts . and - plus look-alikes (• · – — _), with words split by /, | or 2+ spaces; unknown codes become #. Encoding also returns the playing time at a given speed (PARIS timing: dot = 1200/WPM ms). No audio. Web version: https://s3eidat.github.io/morse-code/
| Input | Type | Description |
|---|---|---|
text required | string | Text to encode, or Morse code to decode. |
mode | "encode" | "decode" | "auto" default "auto" | "encode" text → Morse, "decode" Morse → text, or "auto" (default): decode if the input only has Morse symbols, spaces, / and |. |
wpm | number default 18 | Speed in words per minute for the duration estimate (default 18). |
Example
{
"text": "SOS",
"mode": "encode"
}Result
{
"mode": "encode",
"result": "... --- ...",
"skipped": 0,
"durationSeconds": 1.8
}Example
{
"text": ".... .. / - .... . .-. ."
}Result
{
"mode": "decode",
"result": "HI THERE",
"unrecognized": 0
}text_number_to_wordsNumber to words (English & Arabic)
Spell a number in words in English and Arabic: English cardinal (with decimals, optional British "and"), ordinal (twenty-first), cheque wording for an amount in a currency (cents in words or as 25/100, optional "only"), Arabic cardinal, and Arabic tafqeet for amounts with correct gender/number agreement of the currency noun (optional "faqat … la ghayr" wrapper and the modern 100 spelling). Currencies: JOD, USD, SAR, AED, KWD, EGP, GBP (or none). Accepts Arabic-Indic digits and thousands separators. Up to 999 trillion (15 digits). Web version: https://s3eidat.github.io/number-words/
| Input | Type | Description |
|---|---|---|
number required | string | number | The number or amount, e.g. "1500.250", "1,234,567.89", -12.05 (Arabic-Indic digits work too). |
currency | "none" | "JOD" | "USD" | "SAR" | "AED" | "KWD" | "EGP" | "GBP" default "none" | Currency for cheque / tafqeet wording: none (default), JOD, USD, SAR, AED, KWD, EGP, GBP. |
only | boolean default false | Add "only" (English) and the Arabic "faqat … la ghayr" wrapper to amounts. |
british | boolean default false | British English "and": one hundred and five. |
subStyle | "words" | "fraction" default "words" | Cheque sub-units in words (twenty-five cents) or as a fraction (25/100). |
modernHundred | boolean default false | Arabic: use the modern spelling of "hundred" (without the extra alif). |
Example
{
"number": "21"
}Result
{
"digits": "21",
"english": "twenty-one",
"ordinal": "twenty-first",
"ordinalShort": "21st",
"arabic": "واحد وعشرون"
}Example: englishAmount: "One thousand five hundred dollars and twenty-five cents", plus the Arabic tafqeet
{
"number": "1500.25",
"currency": "USD"
}Result
{
"digits": "1,500.25 USD",
"english": "one thousand five hundred point two five",
"arabic": "ألف وخمسمائة فاصلة خمسة وعشرون",
"englishAmount": "One thousand five hundred dollars and twenty-five cents",
"arabicAmount": "ألف وخمسمائة دولار وخمسة وعشرون سنتاً"
}text_readabilityReadability score
Score how easy an English text is to read: Flesch Reading Ease, Flesch-Kincaid Grade, Gunning Fog, SMOG, Coleman-Liau and Automated Readability Index (same formulas, sentence splitter and syllable estimate as the website), plus a verdict, average grade level, and Hemingway-style hints: long sentences (over 20 / 30 words), passive voice and adverbs. The formulas are built for English; for Arabic text the result says so (arabicWarning). Give "text" or a text file "path". Web version: https://s3eidat.github.io/readability/
| Input | Type | Description |
|---|---|---|
text | string | The text to score. |
path | string | Or: a path to a UTF-8 text file. |
Example: Returns all six scores, the verdict and hints.
{
"text": "Keep it short. Use plain words. Readers scan, so put the main point first and cut what they don't need."
}Result
{
"readingEase": 100,
"verdict": "Very easy",
"verdictLevel": "ok",
"advice": "Short sentences and everyday words. Almost anyone can follow it.",
"averageGrade": 1.7,
"averageGradeText": "grade 2 · age 7–8",
"scores": {
"fleschReadingEase": 111.2,
"fleschKincaidGrade": {
"score": -0.6,
"grade": "kindergarten"
},
"gunningFog": {
"score": 2.7,
"grade": "grade 3 · age 8–9"
},
"smog": {
"score": 3.1,
"grade": "grade 3 · age 8–9"
},
"colemanLiau": {
"score": 3,
"grade": "grade 3 · age 8–9"
},
"automatedReadability": {
"score": 0.5,
"grade": "grade 1 · age 6–7"
}
},
"words": 20,
"sentences": 3,
"syllablesPerWord": 1.05,
"wordsPerSentence": 6.7,
"longSentences": [],
"passive": [],
"adverbs": [],
"tips": [
"No long sentences, passive voice or extra adverbs found."
],
"smogNote": "SMOG is designed for 30+ sentences; with 3 it is a rough estimate."
}text_slugifySlugify
Turn titles into clean URL slugs, one slug per non-empty line (bulk). Folds accents (é → e, ß → ss), transliterates Arabic to Latin (the article al- becomes its own word) or keeps Arabic letters, converts Arabic-Indic digits, drops tashkeel, turns & into "and", can remove stop words (English and Arabic) and cap the length at a word boundary. Web version: https://s3eidat.github.io/slugify/
| Input | Type | Description |
|---|---|---|
text required | string | Title(s) to slugify. Each non-empty line becomes one slug. |
separator | "-" | "_" | "." default "-" | Word separator: dash (default), underscore or dot. |
lowercase | boolean default true | Lowercase the slug (default true). |
foldAccents | boolean default true | Transliterate accents: é → e, ß → ss, æ → ae (default true). |
removeStopWords | boolean default false | Remove stop words in English and Arabic such as the, of, and (kept if nothing else is left). |
arabic | "latin" | "keep" default "latin" | "latin" transliterates Arabic letters (default); "keep" keeps them. |
maxLength | integer default 0 | Maximum slug length in characters, cut at a word boundary (0 = no limit). |
Example
{
"text": "Crème Brûlée & Café au Lait: A Love Story"
}Result
{
"slugs": [
{
"title": "Crème Brûlée & Café au Lait: A Love Story",
"slug": "creme-brulee-and-cafe-au-lait-a-love-story",
"length": 42,
"encodedLength": 42
}
]
}Example: lord-rings
{
"text": "The Lord of the Rings",
"removeStopWords": true
}Result
{
"slugs": [
{
"title": "The Lord of the Rings",
"slug": "lord-rings",
"length": 10,
"encodedLength": 10
}
]
}text_social_countSocial media character counter
Check a post against platform limits the way the platforms count: X/Twitter weighted length (links = 23, emoji = 2, CJK = 2; limit 280), Threads 500, Bluesky 300, Instagram 2,200 (+ 30 hashtags), LinkedIn 3,000, Facebook 63,206, TikTok 4,000, YouTube title 100 / description 5,000, Pinterest 500, Google title ~60, meta description ~160. Characters are counted as user-perceived graphemes (one emoji = 1). Also: words, hashtags, mentions, links, emoji, and SMS encoding (GSM-7 vs Unicode) with the number of SMS parts and the characters that force Unicode. Give "text" or a text file "path". Web version: https://s3eidat.github.io/social-counter/
| Input | Type | Description |
|---|---|---|
text | string | The post text. |
path | string | Or: a path to a UTF-8 text file. |
platforms | ("x" | "threads" | "bsky" | "ig" | "li" | "fb" | "tt" | "yt" | "ytd" | "pin" | "gt" | "gd")[] | Only these meters: x, threads, bsky, ig, li, fb, tt, yt, ytd, pin, gt (Google title), gd (meta description). Default: all. |
gsmLookalikes | boolean default false | Also return the text with curly quotes, dashes, ellipses, odd spaces etc. replaced by GSM-7 look-alikes (cheaper SMS). |
Example: xWeightedLength 48: the link counts 23 and the emoji 2.
{
"text": "Read it here: https://example.com/blog/code-reviews 🚀 #coding",
"platforms": [
"x"
]
}Result
{
"characters": 61,
"words": 9,
"hashtags": 1,
"mentions": 0,
"links": 1,
"emoji": 1,
"lines": 1,
"utf16Units": 62,
"xWeightedLength": 48,
"platforms": [
{
"id": "x",
"name": "X (Twitter) post",
"count": 48,
"limit": 280,
"softLimit": false,
"remaining": 232,
"over": 0,
"status": "ok",
"notes": [
"Weighted: links 23, emoji 2, CJK 2. Premium allows 25,000."
]
}
],
"sms": {
"encoding": "UCS-2",
"parts": 1,
"unitsUsed": 62,
"perPart": 70,
"leftInPart": 8,
"nonGsmCharacters": [
{
"char": "🚀",
"count": 1
}
]
}
}text_word_countWord count
Count words, characters (with and without spaces), sentences, paragraphs, lines and unique words; estimate reading (238 wpm) and speaking (150 wpm) time; list the most used keywords with density. Works for English and Arabic (tashkeel ignored). Give "text" or a text file "path". Web version: https://s3eidat.github.io/word-count/
| Input | Type | Description |
|---|---|---|
text | string | The text to analyse. |
path | string | Or: a path to a UTF-8 text file. |
keywords | integer default 12 | How many top keywords to return (0 = none). |
includeStopWords | boolean default false | Count common words like "the"/"في" as keywords. |
Example: 11 words, 4 sentences, 2 paragraphs
{
"text": "Hello world. This is a test! Is it?\n\nNew paragraph here."
}Result
{
"words": 11,
"characters": 56,
"charactersNoSpaces": 45,
"sentences": 4,
"paragraphs": 2,
"lines": 3,
"uniqueWords": 10,
"averageWordLength": 3.73,
"longestWord": "paragraph",
"readingTimeSeconds": 3,
"speakingTimeSeconds": 4,
"keywords": [
{
"word": "hello",
"count": 1,
"density": 9.09
},
{
"word": "new",
"count": 1,
"density": 9.09
},
{
"word": "paragraph",
"count": 1,
"density": 9.09
},
{
"word": "test",
"count": 1,
"density": 9.09
},
{
"word": "world",
"count": 1,
"density": 9.09
}
]
}Developer: data formats
JSON, CSV, YAML, XML, SQL, HTML/CSS formatting and conversion, types from JSON, curl to code.
css_formatCSS beautify / minify
Beautify CSS (one declaration per line, one selector per line, blank line between top-level rules, nested @media blocks) or minify it. Strings, url(...) and escapes are kept intact; calc() spacing is preserved. Optional comment removal (/*! … */ kept). Give "text" or a file "path". Web version: https://s3eidat.github.io/html-css-format/
| Input | Type | Description |
|---|---|---|
text | string | The CSS as inline text. |
path | string | Or: a path to a CSS file (UTF-8; use this for big inputs). |
mode | "beautify" | "minify" default "beautify" | "beautify" (default) or "minify". |
indent | "2" | "4" | "tab" | integer default "2" | Indentation: 2, 4, "tab" (or any number of spaces 0-8). |
removeComments | boolean default false | Drop comments (/*! … */ license comments are kept). |
output | string | Optional: also write the result to this file path (or folder ending in "/"). The result text is then left out of the reply. Results over 1,000,000 characters are always written to a file. |
Example
{
"text": "a,b{color:red;margin:0 auto}"
}Result
{
"result": "a,\nb {\n color: red;\n margin: 0 auto;\n}"
}csv_to_jsonCSV to JSON
Convert CSV/TSV to JSON with an RFC 4180 parser (quoted fields, "" escapes, line breaks inside quotes, CR/LF/CRLF, BOM). Detects the delimiter (comma, semicolon, tab, pipe), uses the first row as headers (blank → column_N, duplicates → name_2), and can type values (numbers, true/false, null; long digit strings like IDs stay strings). Output: array of objects or array of arrays, pretty-printed. Give "text" or a file "path". Web version: https://s3eidat.github.io/csv-json/
| Input | Type | Description |
|---|---|---|
text | string | The CSV as inline text. |
path | string | Or: a path to a CSV/TSV file (UTF-8; use this for big inputs). |
delimiter | "auto" | "," | ";" | "tab" | "\t" | "|" default "auto" | Delimiter: "auto" (detect), ",", ";", "tab" or "|". |
header | boolean default true | First row is a header (default true). |
types | boolean default true | Turn numbers, true/false and empty/null into JSON types (default true). |
shape | "objects" | "arrays" default "objects" | "objects" (one object per row) or "arrays" (rows as arrays). |
output | string | Optional: also write the result to this file path (or folder ending in "/"). The result text is then left out of the reply. Results over 1,000,000 characters are always written to a file. |
Example
{
"text": "id,zip,ok\n1,007,true"
}Result
{
"rows": 1,
"columns": [
"id",
"zip",
"ok"
],
"delimiter": "comma",
"ragged": false,
"result": "[\n {\n \"id\": 1,\n \"zip\": \"007\",\n \"ok\": true\n }\n]"
}s3eidatGPT: summarise PDFs, write, translate and ask questions with AI. Try it free.
Open s3eidatGPT