unifont
  • All fonts Browse or filter the whole catalogue
  • Compare providers One family, every CDN, side by side
  • Documentation Install, providers, custom providers
  • HTTP API The endpoints this site is built on

The site is an API

Every page here is a thin layer over these endpoints. They're public, they need no auth, they're cached, and they won't change while they're under /v1. Use them in scripts, editor plugins or CI checks, anywhere you want font metadata without shipping a resolver. There's an MCP server too, if the thing asking is a model.

Machine-readable: openapi.json describes every endpoint below, llms.txt indexes the site for agents, and every prose page here answers in markdown if you ask for text/markdown or append .md to its path.

Not for production use. This API is best-effort, we'll rate-limit it if we have to, and it can change or go away, the same as proxy.unifont.dev. Build it into a script, an editor plugin or a CI check by all means; if a deployment of yours depends on it, run unifont yourself instead, or self-host the proxy.

GET /api/v1/providers

Every provider, with the number of families it will list.

example

curl https://unifont.dev/api/v1/providers

returns{ providers: [{ name, label, origin, families, requiresOptions, unavailable, note }] }

POST /mcp

MCP server over Streamable HTTP. Point an agent at it and it can search families, read provider metadata, compare CDNs, check unicode coverage, and get CSS it can paste.

example

claude mcp add --transport http unifont https://unifont.dev/mcp

returnsJSON-RPC 2.0. Tools: search_fonts · get_font · get_font_css · compare_providers · check_coverage · list_providers

GET /api/v1/status

How the merged index is doing right now: family counts, which providers answered, and how old the index is.

example

curl https://unifont.dev/api/v1/status

returns{ families, providers, unavailable, indexAge, crossListed }

GET /api/v1/fonts

Search the merged catalogue. Ranked exact → prefix → word → substring. Never fuzzy.

Parameter Type Notes
qstringWhat to search for. Leave it out to list everything.
providerstringLimit to one provider.
limitnumberDefault 60, capped at 200.
offsetnumberDefault 0.
example

curl "https://unifont.dev/api/v1/fonts?q=grotesk&limit=5"

returns{ total, families: [{ family, providers }], unavailable }

GET /api/v1/fonts/{family}

Everything one provider knows about a family, and the faces it resolves to.

Parameter Type Notes
providerstringLimit the cascade to these providers (comma-separated).
weightsstringComma-separated. Defaults to every weight published.
stylesstringComma-separated: normal, italic, oblique.
subsetsstringComma-separated. Defaults to everything published.
example

curl "https://unifont.dev/api/v1/fonts/Newsreader?weights=400,600&subsets=latin"

returns{ family, provider, providers, properties, requested, notes, fonts, fallbacks, css }

GET /api/v1/fonts/{family}/transfer

How much a selection weighs, measured with HEAD requests. Nothing is downloaded.

Parameter Type Notes
weightsstringComma-separated. Default 400.
stylesstringComma-separated. Default normal.
subsetsstringComma-separated. Default latin.
providerstringLimit the cascade to these providers (comma-separated).
example

curl "https://unifont.dev/api/v1/fonts/Fraunces/transfer?subsets=latin,latin-ext"

returns{ family, faces, files, measured, bytes }. `measured` counts the files that reported a content-length

GET /api/v1/fonts/{family}/css

@font-face CSS you can serve. Link to it directly, or read it and copy. If a selection resolves to nothing you get an empty stylesheet with a comment, not a 404.

Parameter Type Notes
providerstringLimit the cascade to these providers (comma-separated).
weightsstringComma-separated. Default 400.
stylesstringComma-separated. Default normal.
subsetsstringComma-separated. Default latin.
asstringRename the family, so you can load several providers at once.
example

curl "https://unifont.dev/api/v1/fonts/Switzer/css?weights=300,500"

returnstext/css

GET /api/v1/css

One stylesheet for lots of families, so a grid of specimens costs one request.

Parameter Type Notes
familiesstringComma-separated, up to 40. Required.
weightsstringComma-separated. Defaults to the variable range, or the weight nearest 400.
subsetsstringComma-separated. Defaults to latin where the family publishes it.
example

curl "https://unifont.dev/api/v1/css?families=Anton,Erode,Spectral"

returnstext/css. A family that can't be resolved becomes a comment, rather than breaking the sheet

GET /api/v1/fonts/{family}/compare

The same family, asked of every provider that doesn't need credentials.

example

curl https://unifont.dev/api/v1/fonts/Inter/compare

returns{ family, results: [{ provider, available, weights, styles, subsets, faces, files, host, fallbacks }] }

GET /api/v1/fonts/{family}/coverage

Which characters the resolved faces can actually draw, based on their unicode-range.

Parameter Type Notes
textstringCheck your own text instead of the built-in samples.
providerstringLimit the cascade to these providers (comma-separated).
example

curl "https://unifont.dev/api/v1/fonts/Anton/coverage?text=Zażółć"

returns{ family, provider, checks: { [name]: { text, unrestricted, covered, missing, subsets } } }

Conventions

Family names
Percent-encode them: /api/v1/fonts/Big%20Shoulders%20Display. Matching ignores case.
Unknown families
404 with a message naming the family. A family may still exist on Adobe Fonts or npm, neither of which can be listed from here.
Partial answers
If a provider fails, the response says so in unavailable, rather than quietly handing you a short list.
Caching
Metadata is cached for an hour and CSS for a day, both with stale-while-revalidate. Font files come from the provider's own CDN. This API never proxies them.