API

Every feature of the site is a plain HTTP request. No key required for the public catalogue.

Stylesheet

Request a family and the weights you need. The response contains a single src per face, negotiated for the requesting browser.

<link rel="stylesheet" href="https://v2.fontapi.ir/css/vazirmatn:400,700">

Several families, one stylesheet

Repeat family to load several families with one request and one <link>. Each takes the same weight syntax as the path form, and d and ur apply to all of them. A collection on this site builds exactly this URL. A custom family name (n) renames one family, so it is accepted only when a single family is requested.

<link rel="stylesheet" href="https://v2.fontapi.ir/css?family=inter:400,700&family=vazirmatn:400&d=swap">

# and the structured equivalent:
curl "https://v2.fontapi.ir/json?family=inter:400,700&family=vazirmatn:400"

Weights and italics

Comma-separate weights. Suffix a weight with i for italic. A weight the family does not ship resolves by the CSS Fonts Level 4 matching rules rather than failing.

https://v2.fontapi.ir/css/ibm-plex-sans:400,400i,700

Weight aliasing

Ask for a source weight but choose how it is labelled in the emitted CSS. Useful when your stylesheet expects font-weight: bold but the face you want is 600.

https://v2.fontapi.ir/css/ibm-plex-sans:600@bold

/* emits: font-weight: bold; using the 600 face */

Custom family name

Serve a font under a different CSS family name, so you can swap the underlying face without touching your stylesheet.

https://v2.fontapi.ir/css/vazirmatn:400?n=Brand%20Sans

/* then: font-family: "Brand Sans", sans-serif; */

font-display

Any value from the CSS enum: auto, block, swap, fallback, optional. Invalid values are rejected with 400 rather than silently ignored.

https://v2.fontapi.ir/css/vazirmatn:400?d=swap

Subsetting

By default each script is a genuinely separate, smaller file with an accurate unicode-range, so the browser downloads only what your page text needs. Latin is typically under 10% of the full face.

/* automatic: the CSS lists one @font-face per subset */
https://v2.fontapi.ir/css/vazirmatn:400

unicode-range override

Request an exact range. If a pre-built subset matches it is served directly; if not, the nearest covering file is used and the JSON response reports subset_fallback so you always know whether you got byte-optimal output.

https://v2.fontapi.ir/css/vazirmatn:400?ur=U%2B0600-06FF

# check what actually happened:
curl "https://v2.fontapi.ir/json/vazirmatn:400?ur=U%2B0600-06FF" | jq .subset_fallback

JSON

The same resolution as CSS, but structured — and unlike CSS it exposes the full format matrix plus the resolved user agent, so you can build your own @font-face rules and see why a format was chosen.

curl "https://v2.fontapi.ir/json/vazirmatn:400,700"

Catalogue

Browse, search and filter the public library. No key required. A filter can repeat: several categories or languages list families in any of them, several scripts list only families that cover all of them. Each listing carries facet counts for its own filters — how many families each value would list if it were added.

https://v2.fontapi.ir/v1/fonts?search=vazir&language=fa
https://v2.fontapi.ir/v1/fonts?category=serif&category=display
https://v2.fontapi.ir/v1/fonts?subset=latin&subset=arabic
https://v2.fontapi.ir/v1/fonts/vazirmatn
https://v2.fontapi.ir/v1/facets

Caching

Font files are immutable: every URL carries a version segment, so the bytes at a given URL never change meaning and responses are served with max-age=31536000, immutable. Stylesheets use a shorter window and are invalidated explicitly when a font is republished, rather than waiting for a TTL to lapse. Byte-range and conditional requests are supported, so a client on a poor connection can resume rather than restart.