TinyLogo Documentation
Get any company's logo as an image URL. Paste one <img>, and it stays current — you never host or update a logo file. Every logo is resolved from the brand's own site and cached, and the API never returns a broken image.
Quick start
- Get a free token in your dashboard.
- Drop it into an image tag on your page:
<img src="https://logo.tinyappmart.com/v1/stripe.com?token=YOUR_TOKEN&size=128">
That's it. To try before signing up, use the test token get-your-free-token (small limit, testing only).
The request
GET https://logo.tinyappmart.com/v1/{brand}
{brand} can be a domain (stripe.com) or just a name (stripe) — both resolve to the same logo. The response is an image (PNG by default). It never 404s: if no real logo is found, a clean generated monogram is returned instead.
Parameters
| Param | Default | Notes |
|---|---|---|
token | — | Required. Your key (or the test token). In the URL, or as an Authorization: Bearer header. |
size | 128 | Square size in pixels, 16–512. |
format | png | One of png, svg, jpg, webp. |
type | icon | Only icon today; wordmark is planned. |
theme | light | Only light today; dark is planned. |
Keys
There are two kinds of key, plus a test token.
Publishable key — pk_live_…
Safe to put in a public page (like Stripe's publishable key). Use it in the <img> URL as ?token=. Bounded by your daily limit, and you can lock it to your own domains.
Secret key — sk_live_…
Backend only — never put it in HTML. Send it as an Authorization: Bearer header. It also unlocks the JSON endpoints.
Test token — get-your-free-token
Works instantly with no signup, on a small limit. For trying it out, not for production. Sign up for a free token before you ship.
Two ways to pass a key: ?token=… in the URL (needed for <img>), or Authorization: Bearer … (for backends).
Tags — per-project usage
Use one key across many projects, and label each so you can see usage split out in your dashboard. You append the project name to the token as <key>.<tag> — the whole thing is one value (drop it straight in a .env), with no extra URL parameter:
<img src="…/v1/stripe.com?token=pk_live_xxx.my-blog&size=128">
A plain token (no .tag) counts under main. Tags are lowercased and limited to letters, numbers and hyphens (My Blog! becomes my-blog). Your dashboard shows a per-tag breakdown under each key. There is a generous cap on distinct tags per key; beyond it, extra tags fold into an other bucket.
Domain lock
Optional. In the dashboard you can restrict a publishable key to specific domains. A request from any other domain is refused, so a copied link stops working elsewhere. Leave it blank and the key works anywhere.
Rotating a key
If a key ever leaks, click Rotate in the dashboard. The old key stops working immediately and you get a fresh one — no other settings change.
Using it from a backend
For a logo on a page, the simplest tool is a publishable pk_ key in the <img> — it's safe in the browser, and the image is served from our edge directly. Use a secret sk_ key with a backend only when you don't want any key visible in the browser. There are two patterns.
Pattern A — Backend proxy
Your page points at your own URL; your server fetches the logo with the secret key and streams it back. The key never leaves your server.
Page:
<img src="/logo/stripe.com">
Node / Express:
app.get("/logo/:brand", async (req, res) => {
const r = await fetch(
`https://logo.tinyappmart.com/v1/${encodeURIComponent(req.params.brand)}?size=128`,
{ headers: { Authorization: `Bearer ${process.env.LOGO_SK}` } }
);
const buf = Buffer.from(await r.arrayBuffer());
res.set("Content-Type", r.headers.get("content-type"));
res.set("Cache-Control", "public, max-age=86400, immutable");
res.send(buf);
});
Python / FastAPI:
@app.get("/logo/{brand}")
async def logo(brand: str):
async with httpx.AsyncClient() as c:
r = await c.get(f"https://logo.tinyappmart.com/v1/{brand}?size=128",
headers={"Authorization": f"Bearer {LOGO_SK}"})
return Response(r.content, media_type=r.headers.get("content-type", "image/png"),
headers={"Cache-Control": "public, max-age=86400, immutable"})
Cache it (the header above, or a CDN) — otherwise every logo flows through your server on every page view.
Pattern B — Fetch once, embed at render time
If you render HTML on the server, fetch the logo once and inline it as a data URI (or save it to your own storage/CDN):
r = httpx.get("https://logo.tinyappmart.com/v1/stripe.com?size=64",
headers={"Authorization": f"Bearer {LOGO_SK}"})
data_uri = "data:%s;base64,%s" % (r.headers["content-type"],
base64.b64encode(r.content).decode())
# render: <img src="{{ data_uri }}">
JSON endpoints
The secret key also unlocks JSON (backend only):
GET /v1/stripe.com/meta → { domain, name, formats, sizes, image_url }
GET /v1/search?q=stripe → [ { name, domain } ] # look up a domain by name
How resolution works
For each brand we try, in order:
- A hand-curated override, if one exists.
- The brand's own site — apple-touch-icon, web-app manifest, or
og:image. - A favicon service.
- A clean generated monogram, so the response is never broken.
The result is cached, so each logo is fetched once and served fast afterward.
Limits
The test token is capped small (for trying only). A free token is generous and covers real projects; one token can be used across all of them. A short per-minute burst limit keeps things fair — normal pages never reach it, since logos are cached. You can see your usage any time in the dashboard.
Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid token. |
403 | Key is domain-locked and this domain isn't allowed. |
429 | Rate limit reached (daily or per-minute). Retry later or use your own token. |
Terms
Company names and logos are the property of their owners; TinyLogo serves them for identification only. See the Terms & Trademark Notice.