Fonts API
Public REST API for searching, downloading and embedding our open-source font library. Compatible with the Google Fonts CSS2 syntax.
A free, public REST API to search, inspect and embed our open-source font library. Compatible with the Google Fonts CSS2 syntax — drop in a tag and you are done.
<!-- Embed a font in your page -->
<link rel="stylesheet" href="https://jinero.online/api/v1/fonts/css?family=Inter:wght@400,700&display=swap">
<style>
body { font-family: "Inter", system-ui, sans-serif; }
</style>
// Search fonts
const r = await fetch("https://jinero.online/api/v1/fonts?name=mono&per_page=10");
const { data } = await r.json();
console.log(data.map(f => f.name));
All read endpoints are public — no key required. Unauthenticated requests are throttled to 60 requests per minute per IP. Authenticated requests get 600 req/min. Generate a token on your profile page (sign in first) — the plaintext value is shown only once on creation; we only store a SHA-256 hash. Send it as either an Authorization Bearer token or an X-API-Token header.
# Public — no auth, 60 rpm per IP
curl https://jinero.online/api/v1/fonts?name=inter
# X-API-Token header — 600 rpm
curl -H "X-API-Token: YOUR_TOKEN" https://jinero.online/api/v1/user
# Bearer (also accepted)
curl -H "Authorization: Bearer YOUR_TOKEN" https://jinero.online/api/v1/user
// Same token, fetch from the browser
const r = await fetch("https://jinero.online/api/v1/user", {
headers: { "X-API-Token": "YOUR_TOKEN" },
});
const me = await r.json();
$user = Http::withHeaders(['X-API-Token' => env('JINERO_API_TOKEN')])
->get("https://jinero.online/api/v1/user")
->json();
Paginated, filterable list of font families. Use this to power a search box, a picker, or pull metadata in bulk.
https://jinero.online/api/v1/fonts
| Parameter | Type | Description |
|---|---|---|
name |
string | Substring match on family name (case-insensitive). |
category |
string|csv | Filter by category: sans, serif, display, handwriting, monospace. |
langs |
csv | Required language subsets, e.g. latin,cyrillic. |
variable |
boolean | Only variable fonts when true. |
monospace |
boolean | Only monospace fonts when true. |
styles_min |
integer | Minimum number of weights/styles. |
styles_max |
integer | Maximum number of weights/styles. |
order |
string | likes (default), downloads, views, name, created_at. |
sort |
string | asc or desc (default desc). |
per_page |
integer | Page size (max 100, default 48). |
page |
integer | Page number (1-based). |
curl "https://jinero.online/api/v1/fonts?name=mono&variable=true&per_page=5"
const params = new URLSearchParams({
name: "mono",
variable: "true",
per_page: "5",
});
const r = await fetch(`https://jinero.online/api/v1/fonts?${params}`);
const { data, total } = await r.json();
$r = Http::get("https://jinero.online/api/v1/fonts", [
"name" => "mono",
"variable" => "true",
"per_page" => 5,
]);
$data = $r->json("data");
{
"current_page": 1,
"per_page": 5,
"total": 23,
"data": [
{
"id": 142,
"name": "JetBrains Mono",
"slug": "jetbrains-mono",
"category": "monospace",
"variable": true,
"langs": ["latin","cyrillic"],
"styles_count": 16,
"downloads": 4821,
"regular_url": "/storage/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2"
}
]
}
Full metadata for a single font family — every weight, every italic, every file URL. Also returns ready-made download/files/css URLs.
https://jinero.online/api/v1/fonts/{slug}
curl https://jinero.online/api/v1/fonts/inter
const r = await fetch("https://jinero.online/api/v1/fonts/inter");
const family = await r.json();
console.log(family.fonts);
$family = Http::get("https://jinero.online/api/v1/fonts/inter")->json();
{
"name": "Inter",
"slug": "inter",
"category": "sans",
"designer": "Rasmus Andersson",
"license": "OFL",
"variable": true,
"styles_count": 18,
"download_url": "https://jinero.online/api/v1/fonts/inter/download",
"files_url": "https://jinero.online/api/v1/fonts/inter/files",
"css_url": "https://jinero.online/api/v1/fonts/css?family=inter",
"fonts": [
{
"weight": 400,
"italic": false,
"style_name": "Regular",
"files": [
{ "format": "woff2", "url": "/storage/fonts/inter/Inter-Regular.woff2", "size": 96241 }
]
}
]
}
Flat list of every font file for a family — handy when you want direct URLs to use in your own @font-face rules.
https://jinero.online/api/v1/fonts/{slug}/files
curl https://jinero.online/api/v1/fonts/inter/files
const r = await fetch("https://jinero.online/api/v1/fonts/inter/files");
const { files } = await r.json();
{
"family": "Inter",
"slug": "inter",
"files": [
{ "weight": 400, "italic": false, "style": "Regular", "format": "woff2", "url": "/storage/fonts/inter/Inter-Regular.woff2", "size": 96241 },
{ "weight": 700, "italic": false, "style": "Bold", "format": "woff2", "url": "/storage/fonts/inter/Inter-Bold.woff2", "size": 99812 }
]
}
Returns a ZIP archive with all WOFF2 files and a ready-to-use fonts.css. Use this when you want to self-host the family.
https://jinero.online/api/v1/fonts/{slug}/download
curl -L -o inter.zip https://jinero.online/api/v1/fonts/inter/download
// Trigger a browser download
window.location.href = "https://jinero.online/api/v1/fonts/inter/download";
Drop-in replacement for the Google Fonts CSS2 API. Loads @font-face rules pointing at our hosted woff2 files. Identical syntax — same family/weight/italic specifiers.
https://jinero.online/api/v1/fonts/css
| Parameter | Type | Description |
|---|---|---|
family |
string | Family slug, optionally followed by axes. Repeat for multiple families. |
display |
string | CSS font-display value: swap (default), auto, block, fallback, optional. |
<!-- Simplest form: regular weight only -->
<link rel="stylesheet" href="https://jinero.online/api/v1/fonts/css?family=inter">
<!-- Specific weights -->
<link rel="stylesheet" href="https://jinero.online/api/v1/fonts/css?family=inter:wght@400,500,700&display=swap">
<!-- Italic + weight tuples (Google syntax) -->
<link rel="stylesheet" href="https://jinero.online/api/v1/fonts/css?family=inter:ital,wght@0,400;1,400;0,700">
<!-- Multiple families -->
<link rel="stylesheet" href="https://jinero.online/api/v1/fonts/css?family=inter:wght@400,700&family=jetbrains-mono:wght@400">
/* Returned content */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://jinero.online/storage/fonts/inter/Inter-Regular.woff2') format('woff2');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('https://jinero.online/storage/fonts/inter/Inter-Bold.woff2') format('woff2');
}
Identify which font is in a cropped text image. There is no OCR step on our side — you must supply the same characters you see in the image via sample_text. The recognizer uses your text to render reference glyphs per candidate font and score them against your image; without it, accuracy drops sharply. Crop tightly to one line of text for best results.
https://jinero.online/api/v1/fonts/recognize
| Parameter | Type | Description |
|---|---|---|
image |
file (multipart) | Tight crop of the text. jpg/jpeg/png/webp/bmp, max 8 MB. |
sample_text |
string | The actual characters in the image. Optional but strongly recommended — ≤160 chars. |
top_k |
integer | Number of matches to return. 3–20, default 8. |
curl -X POST https://jinero.online/api/v1/fonts/recognize \
-F "[email protected]" \
-F "sample_text=The quick brown fox" \
-F "top_k=5"
const form = new FormData();
form.append("image", file);
form.append("sample_text", visibleText); // what your eyes see in the crop
form.append("top_k", "5");
const r = await fetch("https://jinero.online/api/v1/fonts/recognize", { method: "POST", body: form });
const { recognition } = await r.json();
// recognition.matches: [{ slug, name, score, ... }]
$res = Http::attach(
"image",
file_get_contents("crop.png"),
"crop.png"
)->post("https://jinero.online/api/v1/fonts/recognize", [
"sample_text" => "The quick brown fox",
"top_k" => 5,
]);
$matches = $res->json("recognition.matches");
{
"success": true,
"sample_text": "The quick brown fox",
"top_k": 5,
"recognition": {
"matches": [
{ "slug": "inter", "name": "Inter", "score": 0.92, "category": "sans" },
{ "slug": "manrope", "name": "Manrope", "score": 0.88, "category": "sans" },
{ "slug": "plus-jakarta-sans","name": "Plus Jakarta Sans","score": 0.85, "category": "sans" }
],
"method": "glyph-shape",
"elapsed_ms": 2841
}
}
Standard HTTP semantics. Errors return a JSON body with a `message` field (or a CSS comment for the /css endpoint).
// 404 — family not found
{ "message": "Font family not found" }
// 422 — validation (oversized image, wrong mime, bad top_k)
{ "message": "Upload a tight crop of the text to analyze." }
// 422 — recognizer index missing on the server
{ "message": "Recognizer index is missing." }
// 429 — rate limit exceeded (recognize = 3 req/min)
{ "message": "Too Many Attempts." }
// 400 — bad request (CSS endpoint, no family)
/* Missing 'family' parameter */
About the jinero.online Fonts API
Public REST API for searching, downloading and embedding our open-source font library — compatible with the Google Fonts CSS2 syntax.
Drop-in CSS
Same URL shape as Google Fonts CSS2 — swap the host and your existing tags keep working.
Open Licenses
Every family ships with its license and designer metadata. Build catalogs, attribution pages and pickers without scraping.
Self-Hosting
Download a ready-to-use ZIP per family — WOFF2 files plus a generated fonts.css. No build step needed.
No Key Required
Public read endpoints are free with a per-IP rate limit. Generate an API token in your profile when you need higher limits.
Frequently Asked Questions
No. All read endpoints (list, show, files, download, css) are public and rate-limited per IP. You only need a token to favorite fonts on behalf of a user or to get a higher rate limit.
The syntax matches Google Fonts CSS2 (family, wght, ital, display). The family identifier is our slug (e.g. "inter", "jetbrains-mono") rather than the display name with a "+" — slugs are returned by the search endpoint.
WOFF2 for the CSS endpoint and most downloads, with TTF fallbacks for single-style downloads. The /fonts/{slug} endpoint returns every available format with size and URL.
Each font family carries its own license (OFL, Apache, etc.). The license and license_url fields on /fonts/{slug} tell you exactly what is permitted. Always check the source license before commercial use.