Skip to content
HeyMadeFonts

CSS API reference

Two endpoints return @font-face rules for the requested families: https://fonts.heymadefonts.com/css2 (css2 syntax) and https://fonts.heymadefonts.com/css (v1 syntax). Both read only the static catalogue; nothing is fetched from anywhere else.

css2 syntax

One family parameter per family:

Grammar
family=<Name>[:<axis>[,<axis>…]@<tuple>[;<tuple>…]]
  • Name is the family name with spaces written as +. Letters, digits, spaces, hyphens, dots and apostrophes are allowed, up to 80 characters. Matching ignores case, but the returned CSS uses the catalogue’s spelling.
  • Axes are four-letter tags. List lowercase (registered) tags alphabetically, then uppercase custom tags, for example ital,opsz,wght. We accept any order, but this is the canonical form our tools generate.
  • Tuples give one value per listed axis, separated by commas. Separate tuples with ;. A value is a number (400) or a range (100..900).
  • Without an axis list you get the upright regular style, weight 400.

Axis rules

ital
0 (upright) or 1 (italic). Ranges are not allowed.
wght
1 to 1000. A single weight must exist as a static style or fall inside a variable style. A range needs a variable font and must lie inside its weight axis.
wdth
A value or range inside the font’s width axis. The CSS gets a matching font-stretch.
Every other axis (opsz, slnt, GRAD, …)
Ranges only, inside the font’s axis. The variable file always contains the full axis; select values in your CSS with font-variation-settings. A single pinned value returns 422.

css (v1) syntax

Grammar
family=<Name>[:<variant>[,<variant>…]][|<Name>…]

Variants are numeric weights from 100 to 900 in steps of 100, optionally followed by i or italic (700italic, 300i), the shorthands i, italic, b, bi, bolditalic, and weight words: thin, hairline, extralight, ultralight, light, regular, normal, book, medium, semibold, demibold, bold, extrabold, ultrabold, black, heavy (each with an optional italic suffix). Ranges and other axes need css2.

Other parameters

ParameterBehaviour
displayauto, block, swap, fallback or optional, written as font-display in every rule. Other values return 400.
subset, subsetsIgnored. Each style is split into unicode-range slices (latin, latin-ext, cyrillic, …) and browsers download only the slices a page needs.
textNot supported, 422.
effectNot supported, 422.
anything elseRejected with 400.

Response

A successful request returns 200 with Content-Type: text/css; charset=utf-8: one @font-face rule per style and slice, each preceded by a comment naming the slice. For example:

CSS, abridged
/* latin */
@font-face {
  font-family: 'Example';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.heymadefonts.com/files/<sha256>.woff2) format('woff2');
  unicode-range: U+0, U+20-7E, U+A0-FF, …;
}

Errors

Errors are also CSS: a single comment with a stable code and a message.

StatusCodeWhen
400FONT_QUERY_MALFORMEDSyntax error, unknown parameter, invalid display value, missing family.
400FONT_NOT_FOUNDThe family or the requested style is not in the catalogue.
400FONT_QUERY_TOO_LARGEMore than 4,096 characters, 20 families or 64 styles per family, or a stylesheet over 2 MB.
422FONT_QUERY_UNSUPPORTEDtext=, effect=, a weight range on a static family, or a pinned non-CSS axis.
503CATALOG_UNAVAILABLEThe catalogue could not be read. Retry later.

Live examples

Each link below opens a real request against https://fonts.heymadefonts.com using families that are in the catalogue right now.

Prefer curl? Add -i to see the status and caching headers:

Shell
curl -i 'https://fonts.heymadefonts.com/css2?family=Bade+Text:[email protected]'