---
title: "Personalized Rendering"
canonical: https://customerscanvas.com/docs/cc4/web-api-for-rendering.htm
archived: true
applies_to:
  - product: "Customer's Canvas On-Premises"
  - product: "Design Editor"
    versions: ["4.4.25", "4.x (may differ)"]
---

**You’re viewing outdated documentation.** [View the latest Customer’s Canvas On-Premises documentation](https://customerscanvas.com/docs/on-premises/).

# Personalized Rendering

**Applies to:** Customer's Canvas On-Premises; Design Editor 4.4.25, 4.x (may differ) · **Archived documentation**
 
Customer's Canvas provides a Web API to personalize products and render both proof images and hi-res outputs without loading the editor. This API works based on HTTPS requests and is handled by the **Preview** and **HiRes** controllers. It has the following functionality:
 
|  Function |  Request type |  URL |  Description |
| --- | --- | --- | --- |
   |  Generate proof images |  POST |  `~/api/Preview/GeneratePreview` |  Populates a product with personal data, applies color themes, and generates proof images of the product. |
 |  Generate hi-res outputs |  POST |  `~/api/HiRes/GenerateHiRes` |  Populates a product with personal data, applies color themes, and generates high-resolution outputs. |
 
As a result, the **Preview** controller generates temporary URLs that link to proof images. The **HiRes** controller generates state files and URLs that link to high-resolution outputs. Optionally, this controller generates URLs that link to proof images. The response contains an array of the links grouped by products, their surfaces, and mockups: **Array[products][surfaces][mockups]**.
 
The **Preview** and **HiRes** controllers operate in the same way as [Editor.getProofImages](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.editor.getproofimages.htm.md) and [Editor.finishProductDesign](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.editor.finishproductdesign.htm.md).
 
## Request Payload
  
These controllers take the same product definitions as in the IFrame API, substitute personalized data, and return URLs that link to rendered products. You can render a single product or a product group all at once. You can pass the following common data params in the POST request:
 
- **itemsData** sets the content and properties of design elements.
- **productTheme** binds [color themes](https://customerscanvas.com/docs/cc4/product-themes.htm.md) using [IProductThemeConfig](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.configuration.iproductthemeconfig.htm.md).
- **productThemeName** binds color themes using a theme name.
- **productDefinitions** defines an array of products based on [IProductDefinition](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.objectmodel.iproductdefinition.htm.md) or state files.
- **userId** sets the user ID.

Also, the **Preview** controller accepts previewOptions specifying the configuration of proof images, whereas the **HiRes** controller accepts hiResOptions specifying the rendering configuration.
 
#### PreviewOptions
 
The **previewOptions** object defines the size, resizing mode, and rendering configuration of proof images through the following properties.
 
|  Property |  Possible values |  Default values |
| --- | --- | --- |
   |  width |  number |  500 |
 |  height |  number |  500 |
 |  resizeMode |  "Fit", "Fill" |  "Fit" |
 |  proofImageRendering |  [IProofImage](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.objectmodel.iproofimage.htm.md) |  are taken from [clientConfig.json](https://customerscanvas.com/docs/cc4/client-config.htm.md) |
 
You can define these parameters as follows:
 
```
var inputData = {
    previewOptions: {
        width: 504,
        height: 360,
        resizeMode: "Fill",
        proofImageRendering: {
            fileFormat: "jpg",
            showStubContent: true
        }
    },
    ...
};
```
 
#### HiResOptions
 
The **hiResOptions** object allows you to configure the rendering of hi-res outputs, enable the output to separate files, and define whether the controller generates URLs that link to proof images through the following properties.
 
|  Property |  Possible values |  Default values |
| --- | --- | --- |
   |  renderProofImages |  boolean |  false |
 |  renderingConfig.hiResOutputToSeparateFiles |  boolean |  false |
 |  renderingConfig.defaultHiResOuputRendering |  [IHiResOutput](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.objectmodel.ihiresoutput.htm.md) |  are taken from [clientConfig.json](https://customerscanvas.com/docs/cc4/client-config.htm.md) |
 
You can define these parameters as follows:
 
```
var inputData = {
    hiResOptions: {
        RenderProofImages: true,
        renderingConfig:{
            hiResOutputToSeparateFiles: true,
            defaultHiResOuputRendering: {
                fileFormat: "pdf",
                dpi: 400
            }
        }
    },
    ...
};
```
 
#### ItemsData
 
The **itemsData** object allows you to apply properties to all product pages at once and separately on a per-page basis. Also, the **itemsData** object personalizes in-string and interpolation placeholders through the **placeholders** property. This object complies with the following specification.
 
```
itemsData: {
    surfaces: {
        [surfaceName: string]: {
            [itemName: string]: itemData
        }
    },
    [itemName: string]: itemData,
    placeholders: {
        [placeholderName: string]: string;
    }
}
```
 
Here, **itemsData** may contain the following properties.
 
```
itemData: {
  image?: string;        // The path to images.
  contentResizeMode?: string;    // The image insertion mode.
  contentTransform?: Transforms; // Applied transformations.
  opacity?: number;      // The opacity of design elements.
  text?: string;         // The content of text elements.
  leading?: number;      // The text leading.
  tracking?: number;     // The text tracking.
  font?: {
    postScriptName?: string; // The postScript name.
    size?: number;           // The font size, in points.
    fauxBold?: boolean;      // Whether the faux bold is applied.
    fauxItalic?: boolean;    // Whether the faux italic is applied.
  };
  textAlignment?: TextAlignment;
  textVerticalAlignment?: TextVerticalAlignment;
  isVertical?: boolean;  // Whether the text is vertical.
  underline?: boolean;   // Whether the text is underlined.
  location?: PointF;
  size?: ItemSize;       // The width and height.
  color?: string;        // The color in a CSS-compatible format.
  borderColor?: string;  // The border color of design elements.
  borderWidth?: number;  // The border width of design elements.
  fillColor?: string;    // The fill color for shapes.
  altColor?: string;     // The alternate color for dashed lines.
  dashWidth?: number;    // The dash width.
  altDashWidth?: number; // The width of alternate dash lines.
  width?: number;        // The width of lines.
  sourcePoint0?: PointF; // The start point of lines.
  sourcePoint1?: PointF; // The end point of lines.
  barcodeData?: IBarcodeData; // The data encoded into barcodes.
}
```
 
You can define text properties by using the [IFontSettings](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.configuration.ifontsettings.htm.md) interface. [TextAlignment](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.configuration.textalignment.htm.md) and [TextVerticalAlignment](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.configuration.defaultconfig.htm.md) allow you to align text elements. Using [PointF](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.objectmodel.ipointf.htm.md), you can define item coordinates.
 
When populating image placeholders, you can specify the [image insertion mode](https://customerscanvas.com/docs/cc4/image-placeholder.htm.md) and transforms, which should be applied to the placeholder's content. The **contentResizeMode** property can be either `"fit"`, `"fill"`, or `"original"`. You can apply the following **Transforms**:
 
```
Transforms: {
  angle?: number;      // The rotation angle, in degrees.
  scaleX?: number;     // The X-coordinate scaling factor.
  scaleY?: number;     // The Y-coordinate scaling factor.
  translateX?: number; // The X-coordinate movement, in points.
  translateY?: number; // The Y-coordinate movement, in points.
}
```
 
You can specify the content of barcode placeholders by using the [IBarcodeData](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.editor.ibarcodedata.htm.md) interface. For an example, refer to the following section.
 
To set up the size of design elements, use **ItemSize**. For text elements, this object defines the bounding rectangle.
 
```
ItemSize: {
  width: number;
  height: number;
}
```
 
All properties of **itemsData** are optional. Through different variations, you can define any design element supported in Customer's Canvas. The following table details the design elements and their properties that you can pass to the **Preview** and **HiRes** controllers.
 
|  Images |  location, size, image, opacity, borderWidth, borderColor |
| --- | --- |
 |  Image placeholders |  location, size, image, opacity, borderWidth, borderColor, contentResizeMode, contentTransform |
 |  Barcodes |  location, size, barcodeData, opacity, borderWidth, borderColor |
 |  Shapes, ellipses, rectangles |  location, size, fillColor, opacity, borderWidth, borderColor |
 |  Lines |  color, width, opacity, sourcePoint0, sourcePoint1 |
 |  Plain text |  location, text, font, underline, color, isVertical, textAlignment, leading, tracking |
 |  Curved text |  location, size, text, font, underline, color, textAlignment, leading, tracking |
 |  Bounded text |  location, size, text, font, underline, color, isVertical, textAlignment, textVerticalAlignment, leading, tracking |
 |  Path bounded text, auto-scaled text |  location, size, text, font, underline, color, isVertical, textAlignment, leading, tracking |
 
All the numeric values are measured in points. If you do not pass any property that is appropriate to a design element, say **text** for bounded text, then the corresponding value from the design template remains unchanged.
 
**Important** 
The sample below defines the [API security key](https://customerscanvas.com/docs/cc4/webapi.htm.md) in JavaScript code. It could be highly insecure if it runs on a public site. However, you can use it this way in your admin panel, or just for demonstration purposes.
 
## The Personalization Sample
  
The following sample illustrates how you can generate personalized proof images without loading the editor. Replace `example.com` in **baseURL** with the domain name of your site.
 
```html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Proof Images API Sample</title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.js">
    </script>
    <script language="javascript">
    // Set a link to the Preview controller.
    var baseURL = "https://example.com/api/Preview/GeneratePreview";
    // Set a unique key for using the Web API.
    var apiKey = "UniqueSecurityKey";

    // Define a function for obtaining links to proof images.
    var getProofImages = function() {
        // Set up the inputData to personalize the Name layer of the template.
        var inputData = {
            itemsData: {
                "Name": {
                    text: "John Wood",
                    location: { x: 30, y: 30 },
                    font: {
                        postScriptName: "ArialMT",
                        size: 40.5,
                        fauxItalic: true
                    },
                    color: "rgb(255, 0, 100)",
                    textAlignment: "center"
                }
            },
            productDefinitions: [{
                surfaces: ["businesscard_front", "businesscard_back"]
            }],
            userId: "default"
        };

        // Make the request.
        $.ajax({
            url: baseURL,
            type: "POST",
            headers: { "X-CustomersCanvasAPIKey": apiKey },
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify(inputData)
        }).
        fail(function (d) { console.log(d.statusText); }).
        done(function (d) {
            // List the URLs of the proof images.
            d.forEach(function (products) {
                products.forEach(function (surfaces) {
                    surfaces.forEach(function (links) {
                        console.log(links);
                    })
                })
            });
        });
    }
    </script>
</head>

<body>
    <h3>Get Proof Images</h3>
    <input type="button" value="Get" onclick="getProofImages()" />
</body>
</html>
```
 
## Examples of Input Data
  
**productDefinitions** allows you to specify one or more products through [IProductDefinition](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.objectmodel.iproductdefinition.htm.md), which, in turn, allows for setting up the design location, mockups, spines, folding lines, crop marks, and safety lines. Here are several snippets illustrating possible use-cases and input data for these requests. You can copy and paste them into the previous personalization example.
 
#### A proof image of an 8.5x11 inches flyer
 
```
var inputData = {
    previewOptions: {
        width: 504,
        height: 360
    },
    productDefinitions: [{
        surfaces: [{
            designFile: "flyer",
            safetyLines: [{
                margin: 10,
                color: "green",
                altColor: "rgba(255,255,255,0)",
                stepPx: 5,
                widthPx: 1
            }],
            cropMarks: [{
                margin: 10,
                color: "red"
            }]
        }]
    }],
    userId: "default"
};
```
 
#### Personalization of in-string placeholders
 
The following example personalizes the `[#Name]` and `[#Phone]` in-string placeholders, the [specially formatted strings](https://customerscanvas.com/docs/cc4/in-string-placeholders-and-text-validation.htm.md).
 
```
var inputData = {
    itemsData: {
        placeholders: {
            "Name": "John Wood",
            "Phone": "555-123-1234"
        }
    },
    productDefinitions: [{
        surfaces: ["businesscard_front", "businesscard_back"]
    }],
    userId: "default"
};
```
 
#### Personalization of color themes and images
 
For images, you can specify URLs starting from `http://` or `https://` and links to your public and user images through the `public:` and `user:` prefixes, correspondingly. For example, `public:company_logos/aurigma.png` applies the `aurigma.png` logo from the `\company_logos\` subfolder of the public gallery folder.
 
In the following example, state files specify the product.
 
```
var inputData = {
    itemsData: {
        "photo": {
            image: "https://example.com/centralview.jpg",
            opacity: 0.8,
            borderWidth: 1
        },
        "cornerImage": {
            image: "user:tower.jpg",
            size: {
                width: 100,
                height: 100
            }
        }
    },
    productTheme: {
        "mainColor": "rgb(32, 83, 69)",
        "altColor": "rgb(26, 47, 41)",
        "texts": "rgb(176, 143, 37)"
    },
    productDefinitions: [
        "044abd5e-da18-46ff-9053-b019b62baa77",
        "d6c67467-6a3a-466a-9945-288c94b698a3"
    ],
    userId: "default"
};
```
 
#### Personalization of image placeholders with transforms
 
For image placeholders, you can specify how their content should be resized. Also, you can scale, translate, and rotate the content.
 
```
var inputData = {
    itemsData: {
        "logo": {
            image: "public:brand.svg",
            contentResizeMode: "original",
            contentTransform: {
                angle: -90
            }
        },
        "photo": {
            image: "https://example.com/castle.jpg",
            contentResizeMode: "fill",
            contentTransform: {
                angle: 0,
                scaleX: 0.5,
                scaleY: 0.5,
                translateX: 100,
                translateY: 100
            }
        }
    },
    productDefinitions: [{
        surfaces: ["postcard"]
    }],
    userId: "default"
};
```
 
#### Proof images of an envelope with preview mockups
 
In this example, we personalize only the **Front** page of the two-page product.
 
```
var inputData = {
    itemsData: {
        surfaces: {
            "Front": {
                "name": { text: "John Wood" },
                "address": { text: "4414 Hill Road, Perth, IL" },
                "zip": { text: "61701" }
            }
        }
    },
    productDefinitions: [{
        surfaces: [{
            name: "Front",
            previewMockups: [{ up: "envelope" }],
            printAreas: [{
                designFile: "envelopeDesign",
                designLocation: { X: 4.1, Y: 4.1 } 
            }]
        },
        {
            name: "Back",
            printAreas: [{
                designFile: "envelopeBack"
            }]
        }]
    }],
    userId: "default"
};
```
 
#### Personalization of barcode placeholders with validation
 
This example illustrates how you can set up barcodes in the **EAN-8** and **EAN-13** formats and **QR codes** for URLs and phone numbers.
 
```
var inputData = {
    itemsData: {
        "Ean 8": {
            "BarcodeFormat": "EAN_8",
            "BarcodeValue": "1234567"
        },
        "Ean 13": {
            "BarcodeFormat": "EAN_13",
            "BarcodeValue": "123456789012"
        },
        "URL": {
            "BarcodeFormat": "QR_CODE",
            "BarcodeSubType": "Url",
            "Url": "https://example.com"
        },
        "Phone": {
            "BarcodeFormat": "QR_CODE",
            "BarcodeSubType": "Phone",
            "Phone": "5551234567"
        }
    },
    productDefinitions: [{
        surfaces: ["sticker"]
    }],
    userId: "default"
};
```
 
Before the personalization, you can validate the data to be pasted into barcode placeholders by using the following method.
 
```
$.ajax({
    url: "https://example.com/api/Barcode/ValidateBarcodeContent",
    type: "POST",
    headers: { "X-CustomersCanvasAPIKey": apiKey },
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify(
        {
            barcodeFormat: "EAN_13",
            barcodeValue: "1234567890123"
        }
    ).
    done(function (e) { console.log(e); });
});
```
 
This method returns an object implementing [IValidationResult](https://customerscanvas.com/docs/cc4/customerscanvas.iframeapi.editor.ivalidationresult.htm.md).
 
#### Personalization of interpolation placeholders at runtime
 
This example illustrates how you can get a list of variable items including in-string and interpolation placeholders and prepare a payload for these controllers at runtime. To make this example work, add the following text to the canvas:
 `Dear {{Name}}, your order #{{Order}} is ready.` 
Here, we define two interpolation placeholders: `Name` and `Order`. In this example, they take values from the **content** array.
 
```
var baseURL = "https://example.com/api/Preview/GeneratePreview";
var content = [
    { "Name": "John Wood", "Order": "555" },
    { "Name": "Cristopher Bennett", "Order": "123" }
];
// Save the product to get stateId at runtime. 
editor.saveProduct().then(function (result) {
    var stateId = result.stateId;
    editor.getProduct()
        .then(function (product) {
            // Get a list of variable items.
            return product.getVariableItems();
        }).then(function (items) {
            for (var i = 0; i < content.length; i++) {
                var placeholders = {};
                var itemsData = {};
                // Fill in the placeholders.
                items.forEach(function (item) {
                    placeholders[item.name] = (item.name in content[i]) ? content[i][item.name] : "";
                });

                itemsData.placeholders = placeholders;

                // Define inputData to personalize a copy of your product.
                var inputData = {
                    itemsData: itemsData,
                    productDefinitions: [stateId]
                };
                $.ajax({
                    url: baseURL,
                    type: "POST",
                    headers: { "X-CustomersCanvasAPIKey": "UniqueSecurityKey" },
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    data: JSON.stringify(inputData)
                }).
                    fail(function (d) { console.log(d.statusText); }).
                    done(function (d) {
                        d.forEach(function (surfaces) {
                            surfaces.forEach(function (surface) {
                                console.log(surface);
                            });
                        });
                    });
            }
        });
});
```
 
## Responses
  
#### Success Response
 
The following list shows examples of URLs generated by the **Preview** and **HiRes** controllers. As a successful result, this API can return the following URLs:
 
- The preview URL of a one-page product.

    ```
    Status Code: 200 OK
    Content: [[["https://example.com/api/rendering/GetProofImage/default/preview_5603922333D0F6CB246F6AC20DC45552/0_0%5b504x360%5d.png"]]]	
    ```
- The hi-res URLs of two products.

    ```
    Status Code: 200 OK
    Content: [{"StateId":"408693E1872EC277EA28E90E481B2F72",
               "HiResUrls":["https://example.com/api/rendering/GetHiResOutput/default/408693E1872EC277EA28E90E481B2F72/-1_-1.pdf"]},
              {"StateId":"4C042925C4A39E45F886D67B0DE5B4E5",
               "HiResUrls":["https://example.com/api/rendering/GetHiResOutput/default/4C042925C4A39E45F886D67B0DE5B4E5/-1_-1.pdf"]}]
    ```
- The URLs of proof images and hi-res outputs for the previous two products.

    ```
    Status Code: 200 OK
    Content: [{"ProofImageUrls":[["https://example.com/api/rendering/GetProofImage/default/408693E1872EC277EA28E90E481B2F72/0_0.png"],
                                 ["https://example.com/api/rendering/GetProofImage/default/408693E1872EC277EA28E90E481B2F72/1_0.png"]],
               "StateId":"408693E1872EC277EA28E90E481B2F72",
               "HiResUrls":["https://example.com/api/rendering/GetHiResOutput/default/408693E1872EC277EA28E90E481B2F72/-1_-1.pdf"]},
              {"ProofImageUrls":[["https://example.com/api/rendering/GetProofImage/default/4C042925C4A39E45F886D67B0DE5B4E5/0_0.png"],
                                 ["https://example.com/api/rendering/GetProofImage/default/4C042925C4A39E45F886D67B0DE5B4E5/1_0.png"],
                                 ["https://example.com/api/rendering/GetProofImage/default/4C042925C4A39E45F886D67B0DE5B4E5/2_0.png"]],
               "StateId":"4C042925C4A39E45F886D67B0DE5B4E5",
               "HiResUrls":["https://example.com/api/rendering/GetHiResOutput/default/4C042925C4A39E45F886D67B0DE5B4E5/-1_-1.pdf"]}]
    ```

#### Error Response
 
You can obtain the following error responses:
 
- ```
    Status Code: 400 Bad Request
    Content: ProductDefinitions is required.
    ```
- ```
    Status Code: 400 Bad Request
    Content: Image not found: https://example.com/centralview.jpg
    ```
- ```
    Status Code: 403 Forbidden
    Content: Invalid Security Key
    ```
 
## See Also
  
### Manual
 
- [Web API](https://customerscanvas.com/docs/cc4/webapi.htm.md)
- [Product Themes](https://customerscanvas.com/docs/cc4/product-themes.htm.md)
- [In-String Placeholders and Text Validation](https://customerscanvas.com/docs/cc4/in-string-placeholders-and-text-validation.htm.md)
