Sign Customiser

Adds a font to the customiser, at the end of the current presentation order. Only name is required; every other field has a documented default (line_height null, stencil_safe false, every reference null).

POST/api/v3/customisers/{customiser_id}/fonts

Overview

The created font has no typeface. Font-file uploads belong to the deferred file-upload surface, so this operation produces a row the storefront cannot render — font_file.has_font_file comes back false. Upload the typeface in the merchant admin to finish the font. Until that surface ships, the useful operations here are updating and reordering the fonts a customiser already has. A font is priced by the reference its customiser's pricing model needs: a font_tier_id on a customiser priced per sign size, a length_pricing_id on one priced by material length. Creating a font without it is refused with a 422, because the storefront cannot price the font. Every reference must name one of this customiser's own rows. Requires customisers:write and an Idempotency-Key. The write clears the customiser's cached storefront configuration and runs the advisory language sync. It never regenerates Shopify products, product images, or the product cache, so live listings are untouched. Option writes also spend one unit of a separate per-key option-write budget; exhausting it returns a 429 with retry_after.

Authorisation

Bearer token required. Include it in theAuthorization header.

Required scope: customisers:write

Path parameters

customiser_idstringpathrequired

The customiser id.

Example: 1

Request body

namestringbody
line_heightnumberbody
stencil_safebooleanbody
min_height_smallest_letter_cmnumberbody
min_height_uppercase_letter_cmintegerbody
font_tier_idintegerbody
length_pricing_idintegerbody
minimum_size_idintegerbody
minimum_legacy_fixed_height_size_idintegerbody

Request body example

application/json
{
  "name": "Neon Script",
  "line_height": 1.2,
  "stencil_safe": false,
  "min_height_smallest_letter_cm": 4.5,
  "min_height_uppercase_letter_cm": 6,
  "font_tier_id": 7,
  "length_pricing_id": 4,
  "minimum_size_id": 3,
  "minimum_legacy_fixed_height_size_id": 5
}
Create a font
curl https://web.signcustomiser.com/api/v3/customisers/1/fonts \
  --request POST \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Neon Script",
  "line_height": 1.2,
  "stencil_safe": false,
  "min_height_smallest_letter_cm": 4.5,
  "min_height_uppercase_letter_cm": 6,
  "font_tier_id": 7,
  "length_pricing_id": 4,
  "minimum_size_id": 3,
  "minimum_legacy_fixed_height_size_id": 5
}'
Response201
{
  "data": {
    "object": "font",
    "id": 11,
    "customiser_id": 42,
    "name": "Neon Script",
    "line_height": null,
    "uses_default_line_height": true,
    "stencil_safe": false,
    "min_height_smallest_letter_cm": null,
    "min_height_uppercase_letter_cm": null,
    "font_tier_id": 7,
    "length_pricing_id": null,
    "minimum_size_id": null,
    "minimum_legacy_fixed_height_size_id": null,
    "sort_order": 1,
    "font_file": {
      "has_font_file": false,
      "family_name": null,
      "ttf_url": null
    },
    "created_at": "2026-08-13T00:00:00Z",
    "updated_at": "2026-08-13T00:00:00Z"
  },
  "links": {
    "self": "https://web.signcustomiser.com/api/v3/customisers/42/fonts/11",
    "documentation": "https://www.signcustomiser.com/help/api/"
  },
  "meta": {
    "api_version": "v3",
    "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
  }
}
Response400
{
  "type": "https://www.signcustomiser.com/help/api/problems/missing_idempotency_key",
  "title": "Missing idempotency key",
  "status": 400,
  "code": "missing_idempotency_key",
  "detail": "Provide an Idempotency-Key header for this write.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response401
{
  "type": "https://www.signcustomiser.com/help/api/problems/missing_api_key",
  "title": "Missing API key",
  "status": 401,
  "code": "missing_api_key",
  "detail": "Provide a store API key as a bearer token.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response403
{
  "type": "https://www.signcustomiser.com/help/api/problems/insufficient_scope",
  "title": "Insufficient scope",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "This operation requires the customisers:write scope.",
  "required_scopes": [
    "customisers:write"
  ],
  "granted_scopes": [
    "customisers:read"
  ],
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response404
{
  "type": "https://www.signcustomiser.com/help/api/problems/resource_not_found",
  "title": "Resource not found",
  "status": 404,
  "code": "resource_not_found",
  "detail": "The requested resource does not exist or does not belong to the authenticated store.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response409
{
  "type": "https://www.signcustomiser.com/help/api/problems/idempotency_key_conflict",
  "title": "Idempotency key conflict",
  "status": 409,
  "code": "idempotency_key_conflict",
  "detail": "This Idempotency-Key was already used for a different request body on this operation.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response413
{
  "type": "https://www.signcustomiser.com/help/api/problems/request_too_large",
  "title": "Request too large",
  "status": 413,
  "code": "request_too_large",
  "detail": "The request body must not exceed 2 MiB.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response422
{
  "type": "https://www.signcustomiser.com/help/api/problems/validation_failed",
  "title": "Validation failed",
  "status": 422,
  "code": "validation_failed",
  "detail": "This customiser prices fonts by font tier, so every font must name one.",
  "errors": [
    {
      "pointer": "/font_tier_id",
      "code": "font_pricing_required",
      "detail": "Name one of this customiser's font tiers so the storefront can price the font."
    }
  ],
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response429
{
  "type": "https://www.signcustomiser.com/help/api/problems/rate_limited",
  "title": "Too many requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "You have exceeded the request limit for this API key.",
  "retry_after": 37,
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}