Skip to content
HeyMadeFonts

Developer documentation

The HeyMadeFonts CSS API serves our open-source fonts from simple css2 URLs, from https://fonts.heymadefonts.com. No API key, no account, no cookies.

Quick start

Add this to the <head> of your page. It is a working snippet for Bade Text, which is in the live catalogue:

HTML
<link rel="preconnect" href="https://fonts.heymadefonts.com" crossorigin>
<link href="https://fonts.heymadefonts.com/css2?family=Bade+Text:wght@400;700&display=swap" rel="stylesheet">
CSS
body {
  font-family: 'Bade Text', sans-serif;
}

Switching from another font service? Change the stylesheet host to fonts.heymadefonts.com and the family names to ours. The switch tool suggests the closest family and writes the new URL. Every family page in the library builds a snippet for the styles you pick.

Endpoints

EndpointReturns
GET https://fonts.heymadefonts.com/css2?family=…@font-face CSS (css2 syntax)
GET https://fonts.heymadefonts.com/css?family=…@font-face CSS (legacy css syntax)
GET https://fonts.heymadefonts.com/files/{sha256}.woff2Font file, content-addressed and immutable
GET https://fonts.heymadefonts.com/healthJSON with the catalogue version the CDN is serving
https://heymadefonts.com/api/v1/…JSON metadata, downloads, scans and migration; see the JSON API reference

Compatibility matrix

We publish exactly what we support rather than claim full parity. Anything not listed here is rejected with an error, never approximated.

FeatureStatusNotes
css2?family=NameSupportedRegular 400. Spaces as + or %20. Family names are matched case-insensitively.
css2 wght@400;700SupportedWeights 1–1000 that exist in the family.
css2 ital,wght@0,400;1,700Supportedital is 0 or 1.
css2 ranges [email protected]SupportedVariable families only; must lie within the font’s axis.
css2 wdthSupportedPoint or range; emitted as font-stretch.
Other axes (opsz, slnt, GRAD …)Ranges onlyRequest a range within the axis; set values with font-variation-settings. Pinning a single value returns 422.
css?family=A:400,700italic|BSupportedv1 numeric weights, i/italic suffixes and words such as bold, regular, bolditalic.
display=Supportedauto, block, swap, fallback, optional.
Several familiesSupportedRepeat family= (css2) or separate with | (css). Up to 20 families.
subset=IgnoredEvery subset is served as a unicode-range slice; browsers fetch only what a page uses.
text=Not supportedReturns 422. Remove it; slices keep downloads small.
effect=Not supportedReturns 422.
Other parameters (for example WordPress’s ver=)RejectedReturns 400 so typos do not go unnoticed. In WordPress, enqueue with a null version.
Family or style not in the catalogueErrorReturns 400 with a CSS comment that names what is missing. We never substitute another family or weight.

Errors are delivered as a stylesheet so they are visible in the browser’s network panel, for example:

Response body, status 400
/* HeyMadeFonts FONT_NOT_FOUND: Font family "Example Sans" is not in the HeyMadeFonts catalogue. */

Caching

  • Stylesheets (/css, /css2): Cache-Control: public, max-age=86400, stale-while-revalidate=604800. A new catalogue version reaches cached pages within a day.
  • Font files (/files/…): Cache-Control: public, max-age=31536000, immutable. The file name is the SHA-256 of its content, so a file never changes under the same URL.
  • Client errors are cached for 5 minutes; server errors are not cached.

Cookies, CORS and logging

  • The CDN sets no cookies and ignores any it receives.
  • Every response carries Access-Control-Allow-Origin: *, so fonts load from any origin without credentials.
  • Generated CSS contains nothing derived from the visitor’s request. What the servers log, and for how long, is described in the privacy notice.

Content Security Policy

If your site sends a CSP header, allow the CDN for stylesheets and fonts:

HTTP header
Content-Security-Policy: font-src https://fonts.heymadefonts.com; style-src 'self' https://fonts.heymadefonts.com

Merge these sources into your existing directives rather than replacing them. If you use @import inside your own stylesheet, style-src still needs the CDN.

Troubleshooting

The font does not appear and the console mentions “mixed content”
Your page is served over HTTPS but the stylesheet URL starts with http://. Use the https:// URL exactly as shown on the font page.
The console reports a CORS error for a .woff2 file
Fonts are always fetched in CORS mode. Our responses allow every origin, so this usually means a proxy, browser extension or your own server rewrote the response. Check the response headers of the font file in the network panel. For self-hosted fonts on another domain, send Access-Control-Allow-Origin yourself.
The console reports a CSP violation
Add the CDN to font-src and style-src as shown above.
The stylesheet returns 400 or 422
Open the stylesheet URL in a browser tab: the response is a single CSS comment that says what is wrong, such as a weight the family does not have or an unsupported parameter.
Text shows in a fallback font for a moment
That is display=swap working as intended. Use display=optional if you prefer no swap on slow connections, and add the preconnect line to start the connection earlier.

Limits and fair use

Query strings are limited to 4,096 characters, 20 families and 64 styles per family. The service is free; the terms describe fair use and availability. Current health is on the status page.