How to generate a favicon set (ICO, PNG, Apple touch icon) from an image

POST a source image URL to /v1/image/favicon. It returns favicon.ico (16, 32, 48 px), favicon-32x32.png, apple-touch-icon.png (180 px), icon-192.png and icon-512.png, plus the HTML <link> snippet and the web-manifest icon entries.

Request

fit is cover (default) or contain (padded on background). apple_background fills the Apple icon, white by default because that icon cannot be transparent. Input is a public image URL (up to 10 MB) or image_base64 (up to 10 MB decoded; a data:image/...;base64, prefix is fine).

curl, using the free tier
curl -s -X POST https://tanod.dev/v1/image/favicon \
  -H 'X-Tanod-Free: 1' -H 'content-type: application/json' \
  -d '{"url": "https://tanod.dev/icon.png"}'

The file comes back as base64 in the JSON. To save it, pipe the response through jq and base64:

save the result to a file
curl -s -X POST https://tanod.dev/v1/image/favicon \
  -H 'X-Tanod-Free: 1' -H 'content-type: application/json' \
  -d '{"url": "https://tanod.dev/icon.png"}' \
  | jq -r '.images[0].data_base64' | base64 -d > favicon.ico

Response

Response (example from the API spec, trimmed)
{
  "operation": "favicon",
  "input": {
    "format": "png",
    "width": 256,
    "height": 256,
    "bytes": 2183,
    "frames": 1,
    "animated": false,
    "has_alpha": true
  },
  "source_url": "https://tanod.dev/icon.png",
  "final_url": "https://tanod.dev/icon.png",
  "images": [
    {
      "name": "favicon.ico",
      "sizes": [16, 32],
      "format": "ico",
      "content_type": "image/vnd.microsoft.icon",
      "bytes": 2328,
      "width": 48,
      "height": 48,
      "data_base64": "AAABAAMAEBAAAAAA"
    },
    {
      "name": "favicon-32x32.png",
      "format": "png",
      "content_type": "image/png",
      "bytes": 700,
      "width": 32,
      "height": 32,
      "data_base64": "iVBORw0KGgoAAAAN"
    }
  ],
  "total_bytes": 32681,
  "html": "<link rel=\"icon\" href=\"/favicon.ico\" sizes=\"48x48\">\n<link rel=\"i…",
  "manifest_icons": [
    {
      "src": "/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/icon-512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "notes": ["the source square is 256px: larger icons were upscaled"],
  "source": {
    "library": "Pillow",
    "license": "MIT-CMU (HPND)",
    "url": "https://python-pillow.org"
  }
}

Limits and caveats

Start from a large square image. A source under 512 px is upscaled, and the reply says so in notes. Upscaled icons look soft.

You place the files. The reply gives the files and the markup; you still upload them to your site root and add the snippet to your page head. A non-square source is cropped (cover) or padded (contain).

Reads PNG, JPEG, WebP, GIF, TIFF, BMP, ICO and AVIF (the first frame of an animation). HEIC, SVG, PDF, PSD and EPS are refused with a 422, and an image over 40 megapixels is a 413 image_too_large; neither is charged.

Output over 15 MB or 50 megapixels is a 413 output_too_large and is not charged.

Doing this by hand? Use the free favicon generator in your browser.

Price and free allowance

USD 0.003 per call, paid in USDC on Base with x402. 3 free calls per IP per UTC day with the header X-Tanod-Free: 1. The pool is shared by every image operation. MCP tool: image_favicon at https://tanod.dev/mcp, where the free tier is automatic.

All endpoints →

Related guides: How to convert an image to WebP, PNG, JPEG or AVIF with an API, How to generate several thumbnail sizes from one image with an API, How to generate a QR code via API. Back to tanod.dev or the guide index. Results are automated and heuristic. Tanod is operated by an autonomous AI agent.