Favicon API
Turn a single image into a complete favicon package — every size, every platform, a drop-in HTML snippet, and a ready-to-deploy ZIP, over one POST request.
Upload one image, get back a full favicon package: every size every modern browser asks for, plus a site.webmanifest, the HTML snippet ready to paste into <head>, and a ZIP download URL.
# Generate a favicon package
curl -X POST https://jinero.online/api/v1/favicon/generate \
-F "[email protected]" \
-F "app_name=My App" \
-F "theme_color=#0ea5e9"
const form = new FormData();
form.append("image", file);
form.append("app_name", "My App");
form.append("theme_color", "#0ea5e9");
const r = await fetch("https://jinero.online/api/v1/favicon/generate", { method: "POST", body: form });
const { download_url, html_snippet } = await r.json();
All endpoints are public — no key required. Favicon generation runs a Node toolchain (sharp) for every requested size, so the limit is tight.
# Anonymous limits (per IP):
# POST /favicon/generate 3 req/min
# GET /favicon/download/{id} 10 req/min
# Max source image: 10 MB
# Session TTL after generation: 60 minutes
Submit a source image and per-platform flags. Returns a session ID, preview thumbnails, an HTML snippet, and a download URL for the ZIP. Apple, Android and standard favicons are emitted by default; Windows and Yandex are opt-in.
https://jinero.online/api/v1/favicon/generate
| Parameter | Type | Description |
|---|---|---|
image |
file (multipart) | Source image — png, jpg, jpeg, svg, or webp. Max 10 MB. Square images give the best results. |
app_name |
string | Application name written into site.webmanifest. Max 100 chars. |
theme_color |
string | CSS color (hex or rgb) used for the address bar / theme-color meta tag. |
background |
string | Background color used for opaque PNG tiles where transparency is not supported. |
display |
string | Manifest display mode: standalone (default), browser, fullscreen, or minimal-ui. |
orientation |
string | Manifest orientation: any (default), portrait, or landscape. |
apple_icon |
boolean | Emit apple-touch-icon-*.png. Default: true. |
android |
boolean | Emit android-chrome-*.png. Default: true. |
windows |
boolean | Emit mstile-*.png + browserconfig.xml. Default: false. |
yandex |
boolean | Emit yandex-browser-50x50.png + yandex-browser-manifest.json. Default: false. |
curl -X POST https://jinero.online/api/v1/favicon/generate \
-F "[email protected]" \
-F "app_name=Jinero" \
-F "theme_color=#0ea5e9" \
-F "background=#ffffff" \
-F "apple_icon=true" \
-F "android=true" \
-F "windows=true"
const form = new FormData();
form.append("image", logoFile);
form.append("app_name", "Jinero");
form.append("theme_color", "#0ea5e9");
form.append("background", "#ffffff");
form.append("apple_icon", "true");
form.append("android", "true");
const r = await fetch("https://jinero.online/api/v1/favicon/generate", { method: "POST", body: form });
const data = await r.json();
document.querySelector("head").insertAdjacentHTML("beforeend", data.html_snippet);
window.location = data.download_url;
$response = Http::attach(
"image",
file_get_contents("logo.png"),
"logo.png"
)->post("https://jinero.online/api/v1/favicon/generate", [
"app_name" => "Jinero",
"theme_color" => "#0ea5e9",
"apple_icon" => true,
"android" => true,
]);
$package = $response->json();
{
"success": true,
"session_id": "8c1f2e7a-4b5d-4dca-9c3e-1d6f7a0b2c5e",
"file_count": 27,
"html_snippet": "<link rel=\"icon\" type=\"image/x-icon\" href=\"/favicon.ico\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/favicon-32x32.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=\"#0ea5e9\">",
"preview": [
{"label": "favicon-16x16", "url": "..."},
{"label": "favicon-32x32", "url": "..."},
{"label": "apple-touch-icon", "url": "..."},
{"label": "android-chrome-192", "url": "..."}
],
"download_url": "https://jinero.online/api/v1/favicon/download/8c1f2e7a-…",
"expires_in_minutes": 60
}
Stream the generated favicon-package.zip. Sessions stay valid for 60 minutes; afterwards the file is purged from temp storage.
https://jinero.online/api/v1/favicon/download/{session}
curl -L -o favicon-package.zip https://jinero.online/api/v1/favicon/download/8c1f2e7a-…
// Trigger a browser download
window.location.href = data.download_url;
A typical package with defaults (apple + android on, windows + yandex off) contains 16–18 files; with everything enabled, ~27.
favicon.ico # classic multi-resolution ICO
favicon-16x16.png # browser tabs
favicon-32x32.png # browser tabs (retina)
favicon-48x48.png # taskbar
favicon-96x96.png # Chrome desktop shortcut
favicon-192x192.png # PWA / android
favicon-512x512.png # PWA splash
apple-touch-icon.png # iOS home screen (180×180)
apple-touch-icon-152x152.png # iPad
apple-touch-icon-120x120.png # iPhone retina
apple-touch-icon-precomposed.png
android-chrome-192x192.png
android-chrome-512x512.png
android-chrome-maskable-512x512.png
mstile-150x150.png # Windows Start tile (windows=true)
browserconfig.xml # Windows config (windows=true)
yandex-browser-50x50.png # Yandex.Browser (yandex=true)
yandex-browser-manifest.json # Yandex meta (yandex=true)
site.webmanifest # PWA manifest
snippet.html # paste-into-<head> markup
Standard HTTP semantics. Errors return JSON with a "message" field describing the failure.
// 400 — malformed session id on /download
{ "message": "Invalid session id" }
// 404 — session expired or unknown
{ "message": "Result not found or expired" }
// 422 — validation (unsupported file type, oversize image, invalid color)
{ "message": "The image field must be a file of type: png, jpg, jpeg, svg, webp." }
// 429 — rate limit exceeded (/generate = 3 req/min)
{ "message": "Too Many Attempts." }
// 422 — generator crashed (rare; original error is forwarded)
{ "message": "Failed to load source image (corrupt input?)" }
About the jinero.online Favicon API
Free REST API that turns a single source image into a deploy-ready favicon package — every icon size, the PWA manifest, and a drop-in HTML snippet, in one call.
One image in, full kit out
Upload PNG/JPG/SVG/WebP and receive every size browsers ask for — classic favicon.ico, Apple Touch, Android Chrome, PWA, Windows tiles, Yandex.
Drop-in HTML snippet
Response includes the exact <link> and <meta> tags ready to paste into your document <head> — no guessing.
PWA-ready manifest
site.webmanifest is generated with your app name, theme color, background, display mode and orientation — install-as-app works on day one.
No key required
Public endpoint, 3 generations/minute per IP. Get an API token for higher limits.
Frequently Asked Questions
No. The Favicon API is public. /generate is rate-limited to 3 requests/minute per IP because each call runs the sharp toolchain for every requested size. Sign up for an API token if you need more.
A square PNG or SVG at 512×512 or larger gives the best results across all sizes. Anything smaller than 192×192 will look soft on Android home screens. We accept png, jpg, jpeg, svg and webp up to 10 MB.
Classic favicon (ico + 6 PNG sizes), Apple Touch Icon (180/152/120 + precomposed), and Android Chrome (192/512 + maskable). Windows tiles and Yandex.Browser icons are opt-in via the windows=true and yandex=true flags — most modern stacks do not need them.
60 minutes from generation. After that the ZIP and previews are deleted from temp storage. If you need the bundle later, generate it again.
The snippet returned in html_snippet is opinionated and minimal — exactly the tags modern browsers consult. If your CMS needs extra meta tags (Open Graph icons, etc.), append them yourself; the icon paths in the ZIP match what is in the snippet.