Customiser icons
Create an icon
Adds an icon to the customiser, at the end of the current presentation
order. name and svg are required.
The drawing travels as a JSON string rather than a file, so an icon is the
one option a v1 integration can add complete.
Overview
What happens to it is server
side and not negotiable: the SVG is sanitised (scripts, event handlers,
and external references are stripped), converted by the icon service into
the shape a font glyph is cut from, and then the font this customiser's
icons share is rebuilt and each icon's code point stamped back onto its
row. rendered_svg and icon_font report the results and cannot be
written.
A drawing that sanitises to nothing is a 422 on /svg. A converter that
cannot be reached is a 502 icon_conversion_failed, and because all of
the work happens inside the write's transaction, a failure of either kind
leaves no icon and no changed font behind.
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
The customiser id.
Example: 1
Request body
Request body example
{
"name": "Heart",
"svg": "<svg viewBox=\"0 0 24 24\"><path d=\"M4 4h16v16H4z\"/></svg>",
"min_height_cm": 5
}curl https://web.signcustomiser.com/api/v3/customisers/1/icons \
--request POST \
--header 'Accept: application/json' \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"name": "Heart",
"svg": "<svg viewBox=\"0 0 24 24\"><path d=\"M4 4h16v16H4z\"/></svg>",
"min_height_cm": 5
}'{
"data": {
"object": "icon",
"id": 9,
"customiser_id": 42,
"name": "Heart",
"svg": "<svg viewBox=\"0 0 24 24\"><path d=\"M4 4h16v16H4z\"/></svg>",
"rendered_svg": "<svg viewBox=\"0 0 24 24\"><path d=\"M4 4h16v16H4z\"/></svg>",
"min_height_cm": 5,
"icon_font": {
"glyph_code": "f101",
"font_family": "icon-font-a1b2c3d4",
"ttf_url": "https://cdn.signcustomiser.com/icon-fonts/icons.ttf"
},
"sort_order": 1,
"created_at": "2026-08-13T00:00:00Z",
"updated_at": "2026-08-13T00:00:00Z"
},
"links": {
"self": "https://web.signcustomiser.com/api/v3/customisers/42/icons/9",
"documentation": "https://www.signcustomiser.com/help/api/"
},
"meta": {
"api_version": "v3",
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"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"
}{
"type": "https://www.signcustomiser.com/help/api/problems/validation_failed",
"title": "Validation failed",
"status": 422,
"code": "validation_failed",
"detail": "The icon SVG could not be sanitised safely.",
"errors": [
{
"pointer": "/svg",
"code": "invalid_svg",
"detail": "The icon SVG could not be sanitised safely."
}
],
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}{
"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"
}{
"type": "https://www.signcustomiser.com/help/api/problems/icon_conversion_failed",
"title": "Icon conversion failed",
"status": 502,
"code": "icon_conversion_failed",
"detail": "The icon converter could not prepare this drawing, so nothing was written.",
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}