API docs
Icon Horse returns the logo or favicon for any website or product. Give it a domain (stripe.com) or a product name (Microsoft Entra ID) and get back a PNG, WebP, ICO or SVG. Free, no API key, no signup. Every URL below works in an <img> tag, a spreadsheet, a slide or a script.
Machine-readable: openapi.json · llms.txt · llms-full.txt (this page as markdown)
1. Quick start
<img src="https://icon.horse/icon/stripe.com" alt="Stripe" width="32" height="32">
That is the whole integration. The URL returns Stripe's icon as a PNG, up to 256×256. If the site has no icon, you get a letter tile instead of a broken image (or a 404, if you ask for one).
curl -o stripe.png https://icon.horse/icon/stripe.com/128
curl -o entra.png https://icon.horse/name/microsoft-entra-id/128
curl 'https://icon.horse/api/icons?q=stripe.com&q=Microsoft%20Entra%20ID'
2. Icon by domain: /icon/<domain>
| URL | Returns |
|---|---|
/icon/github.com | PNG, the best icon the site has, up to 256px |
/icon/github.com/64 | PNG at 16, 32, 48, 64, 128 or 256px |
/icon/github.com/256/webp | WebP at any allowed size |
/icon/github.com/ico | ICO with 16, 32 and 48px frames |
/icon/github.com/svg | The site's own SVG, or 404 if it has none |
Sizes: 16, 32, 48, 64, 128, 256. Formats: png (default), webp, ico, svg. ICO and SVG take no size. ?size=64 and ?format=webp also work and redirect (301) to the path form.
Paste anything. Scheme, www., path, port and case are dropped, and the request redirects (301) to one canonical URL:
/icon/https://www.Stripe.com/pricing → 301 /icon/stripe.com
/icon/stripe.com?size=64&format=webp → 301 /icon/stripe.com/64/webp
Icon Horse ranks the site's <link rel="icon"> tags, apple-touch-icon, web app manifest icons and /favicon.ico. SVG wins, then the largest size. Parked "domain for sale" pages count as not found.
3. Icon by product name: /name/<product>
Many products do not have their own domain. Microsoft Entra ID lives on microsoft.com; CoCounsel lives on thomsonreuters.com. Ask for them by name:
https://icon.horse/name/microsoft-entra-id
https://icon.horse/name/microsoft-entra-id/128/webp
https://icon.horse/icon?q=Microsoft%20Entra%20ID → 301 /name/microsoft-entra-id
The name becomes a lowercase slug. Sizes, formats and variants work the same as /icon. Names resolve in this order:
- Curated catalog. Hand-checked name → domain or image entries for products that public data gets wrong.
- Wikidata. The query must match whole words in an entity's label or alias, and the entity must have an icon, a logo or an official website. Icon Horse tries the icon, then a square logo, then the website's favicon, then a wide wordmark.
No match means not found. Icon Horse never guesses a logo for a name it does not know.
4. Variants: trim, weight, pad, bg, tone, fallback
Query options that make a row of logos look even. They work on /icon and /name, at every size and raster format.
| Option | Effect |
|---|---|
trim=1 | Cut empty border so the mark fills the frame |
weight=1 | Scale by visual mass, not bounding box, so a solid square and a thin mark look equally heavy. Implies trim |
pad=0..40 | Padding, percent of each side |
bg=white, bg=black, bg=<hex> | Background color. Default is transparent. Hex without #, 3 or 6 digits. With bg set, a logo that will not read on it gets an X-Icon-Warning header |
tone=mono, color=<hex> | Recolor the mark to one color to match a deck. Default color is black or white, whichever reads on bg |
fallback=404 | Return 404 instead of a letter tile when no icon is found |
https://icon.horse/icon/bill.com/128?trim=1&weight=1&pad=8&bg=white
https://icon.horse/icon/stripe.com/64?bg=0a2540
https://icon.horse/icon/example.com?fallback=404
Use fallback=404 with the onerror handler of an <img> when you would rather hide a missing logo than show a letter.
5. Honest response headers
Every image response says what it is. Browsers can read these cross-origin (Access-Control-Expose-Headers is set).
| Header | Meaning |
|---|---|
X-Icon-Fallback | true when the image is a placeholder letter tile |
X-Icon-Source-Size | Original size, such as 48x48, or vector. Under 128px looks soft when scaled up |
X-Icon-Source | The URL the icon came from |
X-Icon-Confidence | 0 to 1. 0 means placeholder |
X-Icon-Stand-In | true when a styled request (weight, pad, bg or tone) got a neutral stand-in tile because no logo exists |
X-Icon-Warning | Problems with a styled icon: low contrast on bg, or tone=mono skipped |
$ curl -sI https://icon.horse/icon/stripe.com/64
HTTP/2 200
content-type: image/png
x-icon-fallback: false
x-icon-source-size: vector
x-icon-confidence: 0.9
x-icon-source: https://images.stripeassets.com/.../favicon.svg
const res = await fetch('https://icon.horse/icon/acme.example')
if (res.headers.get('X-Icon-Fallback') === 'true') {
// No real logo. Show a placeholder of your own, or nothing.
}
6. Icon pages: /site/<domain>
A page for people: the icon, the site's name and description, downloads in every size and format, and copy-paste embed code.
https://icon.horse/site/stripe.com
Downloads: PNG at 16 to 256px, WebP 256px, ICO, and SVG when the site has one.
7. Batch JSON: /api/icons
Resolve up to 20 domains or product names in one call. Each result says whether a real icon was found, how confident the match is, where it came from, and the URLs to use.
curl 'https://icon.horse/api/icons?q=stripe.com&q=Microsoft%20Entra%20ID'
curl -X POST https://icon.horse/api/icons \
-H 'Content-Type: application/json' \
-d '{"q": ["stripe.com", "Microsoft Entra ID", "CoCounsel"]}'
A query with a space, or with no dot, is a product name. Anything else is a domain. Response (shortened):
{
"results": [
{
"query": "Microsoft Entra ID",
"kind": "name",
"found": true,
"fallback": false,
"confidence": 0.85,
"name": "Microsoft Entra ID",
"hostname": "azure.microsoft.com",
"via": "wikidata-logo",
"source": { "url": "https://commons.wikimedia.org/wiki/Special:FilePath/Microsoft%20Entra%20ID%20color%20icon.svg", "format": "svg", "size": "vector" },
"urls": {
"png": "https://icon.horse/name/microsoft-entra-id",
"png_64": "https://icon.horse/name/microsoft-entra-id/64",
"webp": "https://icon.horse/name/microsoft-entra-id/256/webp",
"ico": "https://icon.horse/name/microsoft-entra-id/ico",
"svg": "https://icon.horse/name/microsoft-entra-id/svg",
"page": null
},
"candidates": [ ... ]
}
]
}
| Field | Meaning |
|---|---|
kind | domain or name |
found / fallback | Whether a real icon exists. When found is false, urls is null |
confidence | 0 to 1, same as X-Icon-Confidence |
via | How the icon was found: website, catalog, or a Wikidata source such as wikidata-logo |
source | Original URL, format and size (vector for SVG) |
urls | Ready-to-use links. svg is null when there is no vector; page is null for names |
candidates | Other sources considered, for name lookups |
error | Set instead of the fields above when a query is empty or the host is rejected |
GET responses are cached for 5 minutes. POST is not cached. More than 20 queries returns 400.
8. Force a refresh: /refresh/<domain>
Changed your favicon? Refetch it now:
curl https://icon.horse/refresh/example.com
{"refreshed":true,"changed":true,"purged":true}
Without a refresh, a changed icon shows up within about 2 days on its own.
9. Use in Google Slides, Docs or PowerPoint
Slides and documents accept an image by URL. Use a PNG URL; they do not accept SVG or ICO.
- Google Slides or Google Docs: Insert → Image → By URL. Paste
https://icon.horse/icon/stripe.com/256. - PowerPoint or Word on Windows: Insert → Pictures → This Device, then paste the same URL into the file name box. On Mac or the web, open the URL in a browser, save the PNG, and insert the file.
- Product without a domain: use the name form, such as
https://icon.horse/name/microsoft-entra-id/256.
Tip for an even row of logos: add ?trim=1&weight=1&pad=8&bg=white. Every logo then fills its square the same way on a white tile, so a row of customer or vendor logos lines up.
https://icon.horse/icon/stripe.com/256?trim=1&weight=1&pad=8&bg=white
https://icon.horse/icon/github.com/256?trim=1&weight=1&pad=8&bg=white
https://icon.horse/name/microsoft-entra-id/256?trim=1&weight=1&pad=8&bg=white
Google Sheets works too: =IMAGE("https://icon.horse/icon/stripe.com/64").
10. For AI agents: MCP, stack and logo sets
Agents can call the plain URLs and /api/icons above. Three more endpoints are built for agent workflows; openapi.json has every parameter.
MCP server: /mcp
A remote Model Context Protocol server at https://icon.horse/mcp (Streamable HTTP, no key) with four tools:
find_logos: logos for a list of domains or product names, with confidence and fallback flags.get_logo_image: one logo returned as an image, so the agent can look at it before placing it.logo_set: a matched set of logos for one background color and size, with contrast warnings.company_stack: which tools a company uses, with evidence.
claude mcp add --transport http icon-horse https://icon.horse/mcp
Company stack: /api/stack
Which tools a company uses: client portals, practice software, email, CRM, analytics. It reads the homepage, a few likely pages (client portal, pay, contact) and DNS records. Every tool comes with the evidence that put it there (a link and its text, a script, an MX or TXT record) and a confidence. No observed signal, no tool. A missing tool means no evidence was found, not that the company does not use it.
curl 'https://icon.horse/api/stack?domain=stripe.com'
Logo set: /api/set
A row of logos with the same size, visual weight, padding, background and tone. Parameters: q (repeat, up to 20), size, bg, pad, tone (color or mono), color, gap. Each result adds set_url (the styled image), warnings (for example low contrast on a dark row) and standIn (true when no real logo exists and a neutral tile stands in). row_url renders the whole row as one PNG.
curl 'https://icon.horse/api/set?q=stripe.com&q=Microsoft%20Teams&size=128&bg=ffffff&pad=8'
curl -X POST https://icon.horse/api/set -d '{"q": ["stripe.com", "Microsoft Teams"], "bg": "1f2937", "tone": "mono"}'
11. Caching and limits
- No API key. CORS is open (
Access-Control-Allow-Origin: *). - Icons are cached at the edge for 1 day and refreshed in the background. Letter tiles are cached for 5 minutes, so a site that adds an icon shows up fast.
- Requests that reach the origin are rate-limited per IP: about 60 per minute for icons and pages, 20 per minute for
/api/icons, 5 per minute for/refresh. Edge cache hits do not count. Over the limit returns 429. - Errors are plain text with a 400:
invalid size: must be one of 16, 32, 48, 64, 128, 256.
Need more volume or something custom? [email protected]