Customiser forms
Create a form
Adds a form to the customiser, at the end of the current presentation
order. name and form_type are required; every other property has a
documented default (no receivers, save_customer_details false,
post_submission_action default, and no fields).
fields is the form's field document.
Overview
Each field names the input it
renders as, and only the properties that input reads: a min on a text
field, or options on anything but a dropdown or multiple-choice field,
is a 422 field_not_used_by_input_type on the offending property.
Identities (field_id, option_id) are generated when omitted; send
them back unchanged to keep a field's existing submissions attached to it.
Requires customisers:write and an Idempotency-Key.
The write clears the customiser's cached storefront configuration and runs
the advisory language sync, which is what translates the form's copy into
the customiser's other languages. 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
{
"form_type": "quote",
"post_submission_action": "default",
"fields": [
{
"name": "Email",
"input_type": "email",
"customer_field": "email",
"required": true,
"reply_to": true,
"options": [
{
"label": null,
"value": null
}
]
}
],
"name": "Request a quote",
"description": "Tell us about your project",
"button_label": "Send",
"subject": "New quote request",
"recipient_emails": [
"sales@example.com"
],
"save_customer_details": true,
"redirect_url": "https://example.com/thank-you"
}curl https://web.signcustomiser.com/api/v3/customisers/1/forms \
--request POST \
--header 'Accept: application/json' \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"form_type": "quote",
"post_submission_action": "default",
"fields": [
{
"name": "Email",
"input_type": "email",
"customer_field": "email",
"required": true,
"reply_to": true,
"options": [
{
"label": null,
"value": null
}
]
}
],
"name": "Request a quote",
"description": "Tell us about your project",
"button_label": "Send",
"subject": "New quote request",
"recipient_emails": [
"sales@example.com"
],
"save_customer_details": true,
"redirect_url": "https://example.com/thank-you"
}'{
"data": {
"object": "form",
"id": 7,
"customiser_id": 42,
"name": "Request a quote",
"description": null,
"form_type": "quote",
"button_label": null,
"subject": null,
"recipient_emails": [],
"save_customer_details": false,
"post_submission_action": "default",
"redirect_url": null,
"emails_enabled": true,
"suppressed_emails": [],
"fields": [],
"sort_order": 1,
"created_at": "2026-08-14T00:00:00Z",
"updated_at": "2026-08-14T00:00:00Z"
},
"links": {
"self": "https://web.signcustomiser.com/api/v3/customisers/42/forms/7",
"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/field_not_used_by_input_type",
"title": "Field property not used by this input type",
"status": 422,
"code": "field_not_used_by_input_type",
"detail": "A text field never reads min, so storing it would put a value where nothing looks.",
"errors": [
{
"pointer": "/fields/0/min",
"code": "field_not_used_by_input_type",
"detail": "A text field does not use min."
}
],
"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"
}