Typace API Reference
Typace provides a public API for discovering published font assets, searching the catalog, retrieving a single font record, generating CSS, and inspecting the deployed source revision.
Base URL: https://typace.ace-base.cc
The catalog is derived from the font assets published by the deployment. Use the live response as the source of truth; do not hardcode an inventory or assume every family has every format.
Endpoints
| Method | Endpoint | Purpose |
|---|---|---|
GET | /api/fonts | List the current catalog |
GET | /api/search?q={query} | Search the catalog |
GET | /api/fonts/{slug} | Retrieve one font record |
GET | /api/css/{slug} | Generate a CSS @font-face rule |
GET | /api/commit | Read current source revision metadata |
GET | /api/openapi.json | Read the OpenAPI contract |
All documented endpoints respond to GET, HEAD, and OPTIONS for cross-origin preflight. HEAD returns the same headers with no body. Unsupported methods return 405 Method Not Allowed with an Allow header and a machine-readable error where the response is JSON. API endpoints are limited to 60 requests per minute per client IP by default; set the TYPACE_RATE_LIMIT environment variable to change it. Excess requests receive 429 Too Many Requests, Retry-After, RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset headers, plus a JSON error with code RATE_LIMIT_EXCEEDED. CORS preflight requests are not counted. The limiter is in-memory per serverless runtime, so this is best-effort across multiple Vercel instances rather than a globally coordinated quota.
List fonts
GET https://typace.ace-base.cc/api/fontsReturns a JSON array of published font records. The response is filterable and pageable, and carries a weak ETag.
| Query parameter | Meaning |
|---|---|
format | Filter by file format: ttf, otf, or woff2 |
limit | Maximum records to return (1-500) |
offset | Number of records to skip |
Every response includes an X-Total-Count header with the number of fonts matching the filters, so limit/offset can drive pagination without a second request. When If-None-Match matches the current ETag, the endpoint returns 304 Not Modified with no body, so repeat clients revalidate the catalog for the cost of a header exchange.
// WOFF2 files only, second page of 50
const response = await fetch(
"https://typace.ace-base.cc/api/fonts?format=woff2&limit=50&offset=50"
);
const total = Number(response.headers.get("X-Total-Count"));Font record
| Field | Type | Meaning |
|---|---|---|
name | string | Display name derived from the asset filename |
file | string | Repository-relative asset path |
type | string | File extension: ttf, otf, or woff2 |
format | string | CSS format label: truetype, opentype, or woff2 |
category | string | serif, sans-serif, or unknown |
url | string | Relative URL for the published asset |
sizeBytes | number or null | Published asset size in bytes |
createdAt | string or null | Source creation timestamp from the generated Git-history manifest, when available |
updatedAt | string or null | Source update timestamp from the generated Git-history manifest, when available |
isNew | boolean | True for assets added in a recent catalog batch |
createdAt and updatedAt are populated from the generated Git-history manifest when source timestamps are available. They may be null for assets without reliable history. Use these timestamps for newest-first sorting, and handle null values explicitly. sizeBytes reports the published file size and may be null when it cannot be read. isNew marks assets from a recent catalog batch and should not be read as a popularity or quality signal.
Example
const response = await fetch("https://typace.ace-base.cc/api/fonts");
if (!response.ok) {
throw new Error(`Typace returned HTTP ${response.status}`);
}
const fonts = await response.json();
console.log(fonts);Search fonts
GET https://typace.ace-base.cc/api/search?q=SpectralThe q parameter is optional and limited to 200 characters. Search normalizes terms and matches each term against token prefixes from the font name, file path, type, and format. For example, Ace matches Ace Script without matching Space Grotesk merely because space contains those letters. When q is omitted or empty, the endpoint returns the current catalog.
const query = new URLSearchParams({ q: "Spectral" });
const response = await fetch(
`https://typace.ace-base.cc/api/search?${query}`
);
if (!response.ok) {
throw new Error(`Typace search failed: ${response.status}`);
}
const matches = await response.json();Get one font
GET https://typace.ace-base.cc/api/fonts/{slug}The slug can be a normalized font name or filename. Encode spaces and other reserved characters when constructing the URL. Malformed percent-encoding is rejected as a not-found result rather than causing an unhandled error.
Example:
const slug = encodeURIComponent("Spectral");
const response = await fetch(
`https://typace.ace-base.cc/api/fonts/${slug}`
);
if (response.status === 404) {
throw new Error("Font not found in the current catalog");
}
if (!response.ok) {
throw new Error(`Typace returned HTTP ${response.status}`);
}
const font = await response.json();Generate CSS
GET https://typace.ace-base.cc/api/css/{slug}Returns a CSS @font-face declaration with the resolved asset URL and its actual format. The src URL is absolute, so the rule can be pasted into any stylesheet. The generated declaration uses font-display: swap; applications should still define appropriate weight, style, and fallback families based on the actual font file. The response also sends Link: <asset>; rel=preload; as=font; crossorigin — an early hint that lets the browser begin fetching the font before it parses the CSS. It is cacheable for an hour at the edge (s-maxage=3600) with stale-while-revalidate and stale-if-error, so a temporary origin error keeps serving the last good rule.
const response = await fetch(
"https://typace.ace-base.cc/api/css/Spectral"
);
if (!response.ok) {
throw new Error(`Could not generate font CSS: ${response.status}`);
}
const css = await response.text();Do not assume that an example family or filename exists. Resolve it through the live catalog first.
Current commit metadata
GET https://typace.ace-base.cc/api/commitReturns metadata for the current Vercel deployment commit when deployment Git metadata is available. If deployment metadata is absent, the API attempts to resolve the latest commit on the repository's main branch.
Example response:
{
"sha": "0123456789abcdef0123456789abcdef01234567",
"shortSha": "0123456",
"message": "Improve font catalog metadata",
"date": "2026-10-09T12:00:00Z",
"source": "deployment"
}The SHA and message identify the revision. date is an ISO 8601 timestamp or null if a reliable timestamp cannot be resolved. source is deployment or github. The response intentionally omits repository URLs because the source repository is private. A client can calculate relative time from date, while keeping the absolute timestamp available as a tooltip or accessible label.
Because the Typace repository is private, the deployment needs a server-side GITHUB_TOKEN or GITHUB_PAT with read-only repository access to retrieve commit dates when the Vercel deployment does not supply a valid VERCEL_GIT_COMMIT_AUTHOR_DATE. Preview and production environments must each have the required variable configured. Never expose that token to browser code. If timestamp lookup is unavailable, date correctly remains null and the About UI must not invent relative timing. The endpoint caches successful results briefly and does not return credentials.
OpenAPI
Clients should respect Retry-After and avoid retrying before the specified delay expires.
The machine-readable contract is available at:
https://typace.ace-base.cc/api/openapi.jsonUse this document for client generation and schema-aware integrations. If this human reference and the live OpenAPI contract ever differ, check the currently deployed version before relying on either.
CORS, caching, and errors
- Public read endpoints allow cross-origin requests. Font files under
/fonts/sendAccess-Control-Allow-Origin: *andCross-Origin-Resource-Policy: cross-originso they can be embedded from any origin. - Successful catalog and search responses send a weak
ETagand return304whenIf-None-Matchmatches. - Successful responses use a short browser
max-agewith longers-maxage,stale-while-revalidate, andstale-if-errordirectives, plus aCDN-Cache-Controlheader that sets the edge cache lifetime independently of the browser. - Published font files are content-stable and served with
Cache-Control: public, max-age=31536000, immutableand explicitfont/ttf,font/otf, orfont/woff2content types. - CORS preflight responses are cached for 86400 seconds via
Access-Control-Max-Age. - Unsupported methods return
405and anAllowheader. - Font lookup returns
404when the requested font is not in the current catalog. - Unexpected catalog/search errors return JSON with a stable
codefield. - Commit metadata failures return
502with a machine-readable error code. - Do not assume the API provides authentication, rate-limit guarantees, or a permanent availability SLA unless those are explicitly published by the service.
Licensing
Typace is font delivery infrastructure; it does not make every font's licensing terms identical. Verify the license attached to each typeface before embedding, redistributing, modifying, or bundling it in an application.