Customiser extras
Update an extra
Applies an RFC 7396 JSON Merge Patch to one extra: properties omitted from
the body are unchanged, and null clears a nullable property. Arrays are
replaced wholesale, so sending select_options replaces the whole list of
choices and sending an exclusion list replaces the whole list.
Overview
Read-only
and unknown fields are rejected. An empty object {} is a valid no-op.
Requires customisers:write.
A choice keeps the images uploaded against it as long as its value stays
the same, because image upload is a follow-up surface and a rename must
not destroy a picture the API cannot restore. A choice with a new value
starts without images.
input_type may be changed. The fields the new type does not read are
emptied in the same write, because the read projection publishes them as
null and a row that disagreed with its projection would be unreachable
from either surface.
An Idempotency-Key is optional here: sending one makes the update safe
to retry (an exact repeat replays the original response; the same key with
a different body is a 409). The update clears the customiser's cached
storefront configuration and runs the advisory language sync, and never
regenerates Shopify products, product images, or the product cache.
Authorisation
Bearer token required. Include it in theAuthorization header.
Required scope: customisers:write
Path parameters
The customiser id.
Example: 1
The extra id.
Example: 9
Request body
Request body example
{
"name": "Dimmer",
"description": "Adds a dimmer switch",
"true_label": "Yes please",
"default_value": true,
"base_price": 500
}curl https://web.signcustomiser.com/api/v3/customisers/1/extras/9 \
--request PATCH \
--header 'Accept: application/json' \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"name": "Dimmer",
"description": "Adds a dimmer switch",
"true_label": "Yes please",
"default_value": true,
"base_price": 500
}'{
"data": {
"object": "extra",
"id": 9,
"customiser_id": 42,
"name": "Dimmer",
"description": "Adds a dimmer switch",
"input_type": "yes_no",
"true_label": "Yes please",
"false_label": "No",
"default_value": true,
"char_limit": null,
"yes_colour_exclusions": [
{
"colour_id": 7,
"letter_part": "face"
}
],
"no_colour_exclusions": [],
"select_options": null,
"image_url": null,
"base_price": 500,
"currency": "USD",
"price_multiplier": 0,
"price_multiplier_target": "base_letter_price",
"sort_order": 1,
"created_at": "2026-08-13T00:00:00Z",
"updated_at": "2026-08-13T00:05:00Z"
},
"links": {
"self": "https://web.signcustomiser.com/api/v3/customisers/42/extras/9",
"documentation": "https://www.signcustomiser.com/help/api/"
},
"meta": {
"api_version": "v3",
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
}{
"type": "https://www.signcustomiser.com/help/api/problems/malformed_json",
"title": "Malformed JSON",
"status": 400,
"code": "malformed_json",
"detail": "The request body is not valid JSON: Syntax error.",
"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 request payload failed validation.",
"errors": [
{
"pointer": "/sort_order",
"code": "prohibited",
"detail": "The sort_order field is prohibited."
}
],
"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"
}