Sign Customiser

Store one product created by an enabled custom integration for the authenticated Store and customiser. The response returns the modern product id used by order line items. Sign Customiser also creates a private compatibility projection for the established manufacturer email and export paths. This inbound operation never downloads remote artwork, calls the integration callback, or emits the product-created webhook. Requires products:write. integration_id must identify an enabled custom integration belonging to the Store. store_product_id is the integration's stable external id. This v3 operation rejects an id already present in the Store and serialises concurrent v3 synchronisations. During migration, do not send the same logical product through legacy and v3 writes in parallel. Money is integer minor units and currency must equal the Store currency. Artwork references must be credential-free HTTPS URLs no longer than 255 characters; they are stored as references and are not fetched during this request. Send a unique Idempotency-Key for each logical product. Repeating the exact method, path, body, credential, and key replays the original 201 response with Idempotency-Replay: true and does not create another product. A 409 idempotency_key_in_flight is safe to retry with the same key after retry_after; a key/body conflict needs a new key or the original body. Correct every pointer reported by a 422 before retrying.

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

Authorisation

Bearer token required. Include it in the Authorization header.

Required scope: products:write

Path parameters

customiser_id string path required

Store customiser receiving the product.

Example: 1

Request body

integration_id integer body
store_product_id string body
title string body
description string body
price_amount integer body
compare_at_amount integer body
currency string body
width_cm number body
height_cm number body
length_cm number body
customisations array body
artwork object body

Request body example

application/json
{
  "integration_id": 17,
  "store_product_id": "ext-product-1001",
  "title": "Custom neon sign",
  "description": "Made to order.",
  "price_amount": 12900,
  "compare_at_amount": 14900,
  "currency": "AUD",
  "width_cm": 80.5,
  "height_cm": 31.5,
  "length_cm": 2.5,
  "customisations": [
    {
      "key": "sign_text",
      "label": "Sign text",
      "value": "Hello"
    }
  ],
  "artwork": {
    "preview_image_url": "https://cdn.example.com/sign.png",
    "svg_url": "https://cdn.example.com/sign.svg",
    "outline_image_url": "https://cdn.example.com/sign-outline.png",
    "eps_url": "https://cdn.example.com/sign.eps",
    "illustrator_pdf_url": "https://cdn.example.com/sign.pdf",
    "dxf_url": "https://cdn.example.com/sign.dxf",
    "custom_background_url": "https://cdn.example.com/background.png",
    "custom_background_original_url": "https://cdn.example.com/background-original.png",
    "source_file_url": "https://cdn.example.com/source.ai"
  }
}
Synchronise a product
curl https://web.signcustomiser.com/api/v3/customisers/1/products \
  --request POST \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "integration_id": 17,
  "store_product_id": "ext-product-1001",
  "title": "Custom neon sign",
  "description": "Made to order.",
  "price_amount": 12900,
  "compare_at_amount": 14900,
  "currency": "AUD",
  "width_cm": 80.5,
  "height_cm": 31.5,
  "length_cm": 2.5,
  "customisations": [
    {
      "key": "sign_text",
      "label": "Sign text",
      "value": "Hello"
    }
  ],
  "artwork": {
    "preview_image_url": "https://cdn.example.com/sign.png",
    "svg_url": "https://cdn.example.com/sign.svg",
    "outline_image_url": "https://cdn.example.com/sign-outline.png",
    "eps_url": "https://cdn.example.com/sign.eps",
    "illustrator_pdf_url": "https://cdn.example.com/sign.pdf",
    "dxf_url": "https://cdn.example.com/sign.dxf",
    "custom_background_url": "https://cdn.example.com/background.png",
    "custom_background_original_url": "https://cdn.example.com/background-original.png",
    "source_file_url": "https://cdn.example.com/source.ai"
  }
}'
Response 201
{
  "data": {
    "object": "product",
    "id": 731,
    "customiser_id": 42,
    "title": "Custom neon sign",
    "price_amount": 12900,
    "compare_at_amount": 14900,
    "currency": "AUD",
    "image_url": null,
    "created_at": "2026-07-19T09:15:00Z",
    "updated_at": "2026-07-19T09:15:00Z",
    "description": "Made to order.",
    "width_cm": 80.5,
    "height_cm": 31.5,
    "length_cm": 2.5,
    "artwork": null
  },
  "links": {
    "self": "https://web.signcustomiser.com/api/v3/products/731",
    "documentation": "https://www.signcustomiser.com/help/api/"
  },
  "meta": {
    "api_version": "v3",
    "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
  }
}
Response 400
{
  "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 operation.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response 401
{
  "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"
}
Response 403
{
  "type": "https://www.signcustomiser.com/help/api/problems/insufficient_scope",
  "title": "Insufficient scope",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "This operation requires the products:write scope.",
  "required_scopes": [
    "products:write"
  ],
  "granted_scopes": [
    "products:read"
  ],
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response 404
{
  "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"
}
Response 409
{
  "type": "https://www.signcustomiser.com/help/api/problems/store_product_id_conflict",
  "title": "Store product ID conflict",
  "status": 409,
  "code": "store_product_id_conflict",
  "detail": "This Store has already synchronised a product with the supplied store_product_id. Retry the original request with its original Idempotency-Key, or use a new store_product_id.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response 413
{
  "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"
}
Response 422
{
  "type": "https://www.signcustomiser.com/help/api/problems/validation_failed",
  "title": "Validation failed",
  "status": 422,
  "code": "validation_failed",
  "detail": "One or more request fields are invalid.",
  "errors": [
    {
      "parameter": "currency",
      "pointer": "/currency",
      "code": "invalid_field",
      "detail": "The currency must match the authenticated Store currency."
    }
  ],
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
Response 429
{
  "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": 60,
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}