Fonts are Online Store > Fonts in Store Admin: font families the merchant uploads for their themes and checkout, next to the platform's font library. These endpoints accept Store Admin API tokens and connected AI tools only; app tokens are refused with STORE_API_ADMIN_TOKEN_REQUIRED. Reads require read_storefront; changes require write_storefront.
A font's handle (store:<id>) is a value for a theme's font_picker setting (see Section schema) and for the checkout font, alongside the library's handles. Themes never see font files: the storefront adds the @font-face rules and serves the files from the store's own domains only, so other sites cannot use them.
To add a font, create a font upload with the file's exact size, PUT the file to the returned signed URL, then upload the font with the upload_id. WOFF2, WOFF, TTF and OTF files of up to 2 MB are accepted; each is checked with OTS, the sanitizer Chrome and Firefox use, and stored and served as WOFF2. The family name, weight (a range for variable fonts) and style come from the font itself. A store has at most 20 fonts with up to 4 files each; add a face to a font with font_id.
Every upload needs the merchant's confirmation of the licence statement in List fonts: send licence_accepted: true and the statement's version as terms_version only after the merchant has read and confirmed it. Each upload records that acceptance (the statement, the token or connected user, and the file's checksum); deleting a font keeps the record. A font that a theme or the checkout still uses cannot be deleted (FONT_IN_USE, with error.details.used_in).
Endpoints#
List fonts
List the store's own fonts, the limits and the licence statement.
Returns every font family the store uploaded, oldest first, each with its faces (weight, style and stored size in bytes). handle is the value a theme's font_picker setting and the checkout font take (store:<id>); the library fonts keep their own handles. limits are store-wide: at most max_families families, max_faces faces per family and max_file_bytes per uploaded file. licence is the statement the merchant confirms on every upload, in the request language (English by default), with its version. Admin tokens only: Store Admin API tokens and connected AI tools can call this endpoint; app tokens are refused with STORE_API_ADMIN_TOKEN_REQUIRED.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
Create a font upload
Get a signed URL to upload one font file to.
Upload the file's bytes with HTTPS PUT to the returned url within expires_in seconds, sending every returned header unchanged (the headers are signed; do not send the Store API bearer token there). size_bytes must be the file's exact size, at most 2 MB. Then call Upload a font with the returned upload_id. An upload that is never turned into a font is discarded. Admin tokens only: Store Admin API tokens and connected AI tools can call this endpoint; app tokens are refused with STORE_API_ADMIN_TOKEN_REQUIRED.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
size_bytes
required
|
integer |
The font file's exact size in bytes. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
400STORE_API_INVALID_REQUEST_BODYThe request body is not valid JSON or
size_bytesis missing. -
413FONT_FILE_TOO_LARGEsize_bytesis abovemax_file_bytes. -
400STORE_API_BODY_PROPERTY_UNKNOWNThe body has a property this request does not accept. The message and
error.details.propertieslist the allowed and required properties (nestedfor each object or list of objects). -
400STORE_API_BODY_PROPERTY_INVALIDA body property has the wrong type (
error.details.expected_type). The message anderror.details.propertieslist the allowed and required properties.
Upload a font
Turn an uploaded file into a store font, or add a face to one.
Accepts WOFF2, WOFF, TTF and OTF files; the file's own bytes decide the format, not its name. The file is checked with OTS, the sanitizer Chrome and Firefox use, and refused with FONT_FILE_INVALID when it fails; a font whose licence bits forbid embedding is refused with FONT_LICENCE_RESTRICTED. Weight, style and the family name are read from the font itself (a variable font's weight axis gives a range such as 100 900). It is stored and served as WOFF2, only from the store's own domains. Without font_id a new family is created (FONT_LIMIT_REACHED past max_families); with it the face joins that family (FONT_LIMIT_REACHED past max_faces, FONT_FACE_EXISTS when the family already has that weight and style). The merchant must have read and confirmed the licence statement from List fonts: send licence_accepted: true and its version as terms_version, else FONT_LICENCE_NOT_ACCEPTED. Ask the merchant first; never accept it on their behalf. Every upload records the acceptance with the token, the statement and the file's checksum. Admin tokens only: Store Admin API tokens and connected AI tools can call this endpoint; app tokens are refused with STORE_API_ADMIN_TOKEN_REQUIRED.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
upload_id
required
|
string |
|
licence_accepted
required
|
boolean |
|
terms_version
required
|
string |
The licence statement's |
font_id
|
string |
Add the file as another face of this font instead of creating a new font. |
display_name
|
string |
Name shown in pickers, up to 80 characters. Default: the font's own family name. Ignored with |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
403STORE_API_ADMIN_TOKEN_REQUIREDApp tokens cannot upload fonts.
-
400STORE_API_INVALID_REQUEST_BODYThe request body is not valid JSON or a required field is missing.
-
404NOT_FOUNDupload_idnames no uploaded file, orfont_idno font of this store. -
413FONT_FILE_TOO_LARGEThe uploaded file is above
max_file_bytes. -
422FONT_FILE_INVALIDThe file is not a WOFF2, WOFF, TTF or OTF font, or the font sanitizer refused it.
-
422FONT_LICENCE_RESTRICTEDThe font's licence bits forbid embedding it in a website.
-
422FONT_LICENCE_NOT_ACCEPTEDlicence_acceptedis nottrueorterms_versionis not the current statement's version. -
422FONT_LIMIT_REACHEDThe store already has
max_familiesfonts, or the fontmax_facesfaces. -
409FONT_FACE_EXISTSThe font already has a face with this weight and style.
-
400STORE_API_BODY_PROPERTY_UNKNOWNThe body has a property this request does not accept. The message and
error.details.propertieslist the allowed and required properties (nestedfor each object or list of objects). -
400STORE_API_BODY_PROPERTY_INVALIDA body property has the wrong type (
error.details.expected_type). The message anderror.details.propertieslist the allowed and required properties.
Rename a font
Change the name a font shows in pickers.
Only display_name changes; the family name in the CSS stays the font's own. Pages pick up the new name in theme and checkout pickers right away. Admin tokens only: Store Admin API tokens and connected AI tools can call this endpoint; app tokens are refused with STORE_API_ADMIN_TOKEN_REQUIRED.
Path parameters
| Name | Type | Description |
|---|---|---|
fontId
required
|
uuid |
Font id from List fonts. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
display_name
required
|
string |
Name shown in pickers, 1 to 80 characters. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
403STORE_API_ADMIN_TOKEN_REQUIREDApp tokens cannot manage fonts.
-
404NOT_FOUNDThe font does not exist in this store.
-
400INVALID_INPUTdisplay_nameis empty or longer than 80 characters. -
400STORE_API_BODY_PROPERTY_UNKNOWNThe body has a property this request does not accept. The message and
error.details.propertieslist the allowed and required properties (nestedfor each object or list of objects). -
400STORE_API_BODY_PROPERTY_INVALIDA body property has the wrong type (
error.details.expected_type). The message anderror.details.propertieslist the allowed and required properties.
Delete a font
Delete a font and its files.
A font selected in any theme's settings or in a storefront's checkout branding is refused with FONT_IN_USE; error.details.used_in lists where (kind theme with the theme's name, or checkout). Pick another font there first. Deleting removes the font's files; the licence acceptances recorded at upload are kept. Answers HTTP 204 with no body. Admin tokens only: Store Admin API tokens and connected AI tools can call this endpoint; app tokens are refused with STORE_API_ADMIN_TOKEN_REQUIRED.
Path parameters
| Name | Type | Description |
|---|---|---|
fontId
required
|
uuid |
Font id from List fonts. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
403STORE_API_ADMIN_TOKEN_REQUIREDApp tokens cannot manage fonts.
-
404NOT_FOUNDThe font does not exist in this store.
-
409FONT_IN_USEThe font is selected in a theme or the checkout;
error.details.used_inlists where.