GET /v1/fonts

The 62 bundled families, and the substitution rule.

The renderer never touches the network while it prints, so a document can only use a typeface we bundle. This endpoint is that list. It needs no API key — the catalogue is not account data, and an agent that just received a 400 unknown_font has to be able to read it immediately.

GET/v1/fontsPublic

Response

json
{
  "default": "Inter",
  "count": 62,
  "families": ["Abril Fatface", "Albert Sans", "Alex Brush", "…"],
  "note": "…"
}

families is sorted alphabetically and is the whole truth: a family that is not in it is not on the machine. The response is cacheable for an hour.

Example request

bash
curl -s https://api.pixldocs.com/v1/fonts

Which rule applies to you

There are two behaviours, and the one you get depends on where the markup came from. The difference is deliberate.

A saved template — created through POST /v1/templates or edited in our editor — is resolved once, at save time. If the markup you send names a family we do not bundle, the stack is read the way a browser reads it and pinned to a single bundled family in the STORED source, and the write response carries a font_substitutions array naming every rewrite. What you then read in the editor is exactly what renders, on the first render and every one after. Renders themselves stay strict: a saved source that still names an unbundled family is 400 unknown_font.

Ad-hoc markup sent to POST /v1/render/html or POST /v1/render/url is read as CSS defines it. font-family: Helvetica, Arial, sans-serif is an ordered list of preferences ending in a generic, not a demand for Helvetica — so we resolve it the way a browser would (first bundled family wins, the generic tail decides the class) and pin the result to one literal family. That resolution is deterministic and it is never silent: every stack we rewrite comes back on X-Pixldocs-Font-Substituted.

The generic classes land on sans-serif → Inter, serif → Lora, monospace → JetBrains Mono, cursive → Dancing Script.

Name a bundled family first in every stack and the substitution header is absent from the response. That is the assertion to make in CI if the exact typeface matters to you — it is cheaper than diffing pixels.

Characters, not just families

A bundled family still has to contain the glyphs you send it. Text in a script the chosen family does not cover is refused before it renders rather than printed as boxes, and the error names the characters. Devanagari, CJK and similar scripts need a family that covers them — Noto Sans is the broadest one bundled.