# POST Synchronise a product

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.

- Source URL: https://www.signcustomiser.com/help/api/v3-post-synchronise-a-product/
- Markdown URL: https://www.signcustomiser.com/help/api/v3-post-synchronise-a-product.md
- Group: Products
- Method: POST
- Path: /api/v3/customisers/{customiser_id}/products
- Auth: Bearer token
- Required scopes: `products:write`

## Path parameters

- customiser_id (string, required): Store customiser receiving the product. Example: 1

## Body parameters

- integration_id (integer, optional): No description provided.
- store_product_id (string, optional): No description provided.
- title (string, optional): No description provided.
- description (string, optional): No description provided.
- price_amount (integer, optional): No description provided.
- compare_at_amount (integer, optional): No description provided.
- currency (string, optional): No description provided.
- width_cm (number, optional): No description provided.
- height_cm (number, optional): No description provided.
- length_cm (number, optional): No description provided.
- customisations (array, optional): No description provided.
- artwork (object, optional): No description provided.

## Request body example

```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"
  }
}
```

## cURL example

```bash
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 examples

### 201 POST 201 example 1

```json
{
  "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"
  }
}
```

### 400 Missing idempotency key

```json
{
  "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"
}
```

### 401 Missing or invalid API key

```json
{
  "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"
}
```

### 403 Insufficient scope

```json
{
  "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"
}
```

### 404 Unknown or foreign resource

```json
{
  "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"
}
```

### 409 External product already exists

```json
{
  "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"
}
```

### 413 Request body too large

```json
{
  "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"
}
```

### 422 Invalid request field

```json
{
  "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"
}
```

### 429 Rate limited

```json
{
  "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"
}
```
