Sube una imagen y recibe un paquete completo de favicons: todos los tamaños que piden los navegadores modernos, además de un site.webmanifest, el fragmento HTML listo para pegar en <head> y una URL de descarga del ZIP.

# 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();

Todos los endpoints son públicos: no se necesita clave. La generación de favicons ejecuta herramientas de Node (sharp) para cada tamaño solicitado, así que el límite es estricto.

# 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

Envía una imagen de origen y los indicadores de cada plataforma. Devuelve un ID de sesión, miniaturas de vista previa, un fragmento HTML y una URL de descarga del ZIP. Los favicons de Apple, Android y estándar se generan de forma predeterminada; los de Windows y Yandex son opcionales.

POST https://jinero.online/api/v1/favicon/generate
ParámetroTipoDescripción
image archivo (multipart) Imagen de origen: png, jpg, jpeg, svg o webp. Máximo 10 MB. Las imágenes cuadradas dan los mejores resultados.
app_name string Nombre de la aplicación que se escribe en site.webmanifest. Máximo 100 caracteres.
theme_color string Color CSS (hex o rgb) para la barra de direcciones / la metaetiqueta theme-color.
background string Color de fondo para los mosaicos PNG opacos donde no se admite transparencia.
display string Modo de visualización del manifiesto: standalone (predeterminado), browser, fullscreen o minimal-ui.
orientation string Orientación del manifiesto: any (predeterminado), portrait o landscape.
apple_icon boolean Genera apple-touch-icon-*.png. Predeterminado: true.
android boolean Genera android-chrome-*.png. Predeterminado: true.
windows boolean Genera mstile-*.png + browserconfig.xml. Predeterminado: false.
yandex boolean Genera yandex-browser-50x50.png + yandex-browser-manifest.json. Predeterminado: 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();
Ejemplo de respuesta
{
  "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
}

Descarga el favicon-package.zip generado. Las sesiones son válidas durante 60 minutos; después, el archivo se elimina del almacenamiento temporal.

GET 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;

Un paquete típico con los valores predeterminados (apple + android activados, windows + yandex desactivados) contiene 16–18 archivos; con todo activado, ~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

Semántica HTTP estándar. Los errores devuelven un JSON con el campo "message", que describe el fallo.

// 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?)" }

Acerca de la Favicon API de jinero.online

API REST gratuita que convierte una sola imagen en un paquete de favicons listo para desplegar: todos los tamaños de icono, el manifiesto PWA y un fragmento HTML listo para pegar, en una sola llamada.

Una imagen de entrada, un kit completo de salida

Sube un PNG/JPG/SVG/WebP y recibe todos los tamaños que piden los navegadores: el clásico favicon.ico, Apple Touch, Android Chrome, PWA, mosaicos de Windows y Yandex.

Fragmento HTML listo para pegar

La respuesta incluye las etiquetas <link> y <meta> exactas, listas para pegar en el <head> de tu documento, sin tener que adivinar nada.

Manifiesto listo para PWA

site.webmanifest se genera con el nombre de tu aplicación, el color del tema, el fondo, el modo de visualización y la orientación: la instalación como aplicación funciona desde el primer día.

No requiere clave

Endpoint público, 3 generaciones/minuto por IP. Obtén un token de API para tener límites más altos.

Preguntas frecuentes

No. La Favicon API es pública. /generate tiene un límite de 3 solicitudes/minuto por IP porque cada llamada ejecuta sharp para cada tamaño solicitado. Regístrate y obtén un token de API si necesitas más.

Un PNG o SVG cuadrado de 512×512 o más da los mejores resultados en todos los tamaños. Cualquier imagen de menos de 192×192 se verá borrosa en la pantalla de inicio de Android. Aceptamos png, jpg, jpeg, svg y webp de hasta 10 MB.

El favicon clásico (ico + 6 tamaños PNG), Apple Touch Icon (180/152/120 + precomposed) y Android Chrome (192/512 + maskable). Los mosaicos de Windows y los iconos de Yandex.Browser son opcionales y se activan con los indicadores windows=true y yandex=true; la mayoría de los stacks modernos no los necesitan.

60 minutos desde la generación. Después, el ZIP y las vistas previas se eliminan del almacenamiento temporal. Si necesitas el paquete más tarde, vuelve a generarlo.

El fragmento que se devuelve en html_snippet es deliberadamente mínimo: exactamente las etiquetas que consultan los navegadores modernos. Si tu CMS necesita metaetiquetas adicionales (iconos de Open Graph, etc.), añádelas por tu cuenta; las rutas de los iconos del ZIP coinciden con las del fragmento.