Introducing the Osintly Logo Service
Fetch domain logos as images via a simple GET request. No auth, CORS enabled, served from the edge.
Introducing the Osintly Logo Service
One URL. Any domain. No auth required.
We quietly shipped something we kept using internally and never documented: a logo resolution API. Today we're making it public.
https://logos.osint.ly/{domain} — that's it.
What it does
You send a GET request with a domain. You get back a logo image — PNG, SVG, or ICO, depending on what's available. No redirects, no wrappers, no JSON envelope. Just the image, served directly from the edge.
https://logos.osint.ly/github.com
https://logos.osint.ly/stripe.com
https://logos.osint.ly/openai.comWe also strip www. automatically, so www.github.com resolves to the same thing as github.com.
Why we built it
Inside Osintly, every investigation card that involves a domain or company shows a logo. We needed a fast, reliable way to resolve those logos without hammering external services or bloating our backend. So we built our own.
After using it in production for a while, we realized there was no good reason to keep it internal. If you're building any kind of tool that deals with domains — OSINT tooling, threat intel dashboards, link previews, contact enrichment — you probably need this too.
No API key. No auth. CORS enabled.
The service is fully open:
GET the URL.Access-Control-Allow-Origin: *), so you can call it directly from any frontend without a proxy.Drop it anywhere
<!-- HTML -->
<img src="https://logos.osint.ly/github.com" alt="GitHub logo" />// React
<img src={`https://logos.osint.ly/${domain}`} alt={`${domain} logo`} />// JavaScript
const res = await fetch('https://logos.osint.ly/stripe.com');
const blob = await res.blob();/* CSS */
.logo {
background-image: url('https://logos.osint.ly/github.com');
}HTTP responses
| Code | Meaning |
|---|---|
200 | Logo found and returned |
400 | Missing or invalid domain |
404 | No logo found for this domain |
429 | Rate limited — retry after 60 seconds |
405 | Method not allowed (only GET, HEAD, OPTIONS) |
Response headers
Every successful response includes:
| Header | Example | Description |
|---|---|---|
Content-Type | image/png, image/svg+xml | MIME type of the logo |
Cache-Control | public, s-maxage=2592000, max-age=86400 | Edge: 30d / Browser: 1d |
Access-Control-Allow-Origin | * | CORS, no proxy needed |
X-Logo-Source | hunter, google, r2 | Source used to resolve the logo |
The X-Logo-Source header tells you where the logo came from — useful for debugging or understanding coverage.
Rate limiting
The service allows 1,000 requests per minute per IP on non-cached requests. Cache hits don't count toward this limit — and given the long TTLs, most requests in practice will be cached.
If you exceed the limit:
HTTP 429 Too Many Requests
Retry-After: 60Start using it
No signup. No API key. No docs to read beyond this post.
https://logos.osint.ly/{domain}Full documentation is available at docs.osint.ly.
If you build something with it or run into edge cases (pun intended), let us know — we're on X/Twitter and always reading.
On this page
Share this post
Related posts
View all
Announcements
Announcements
AnnouncementsExplore more from Osintly
Osintly
Start your first investigation today.
900+ OSINT modules. AI analyst built-in. Real-time data. Everything you need in one place.