> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pictify.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Template

> Create a template with either the Handlebars HTML engine or the FabricJS canvas engine.

Pictify templates come in two flavours. Pick one with the `engine` field.

| Engine | Authoring surface | Use it when |
| - | - | - |
| `html` | Raw HTML + Handlebars (`{{var}}`, `{{#each}}`, `{{#if}}`, helpers) | You want full control over markup, CSS, and copy-paste-able source. |
| `fabric` | FabricJS canvas JSON | You're exporting from the dashboard editor or automating canvas layouts. |

<Note>
  If you omit `engine`, Pictify infers it from the payload: a request with `html` and no
  `fabricJSData` becomes an `html` template; anything else is `fabric`. Set it explicitly
  anyway so the intent is clear.
</Note>

## Handlebars HTML templates

Set `engine: "html"` and pass your template source in `html`. Pictify compile-validates
it on save and fails with HTTP 422 if a block is unclosed or a helper is unknown.

```bash cURL theme={null}
curl -X POST https://api.pictify.io/templates \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "OG Image",
    "engine": "html",
    "width": 1200,
    "height": 630,
    "html": "<div style=\"width:1200px;height:630px;padding:64px;font-family:Inter\"><h1 style=\"font-size:72px\">{{title}}</h1><p style=\"font-size:32px;color:#6b7280\">{{subtitle}}</p>{{#if showCta}}<button>{{ctaText}}</button>{{/if}}</div>",
    "variableDefinitions": [
      { "name": "title", "type": "text", "defaultValue": "Hello world" },
      { "name": "subtitle", "type": "text" },
      { "name": "ctaLabel", "type": "text", "defaultValue": "Learn more" },
      { "name": "ctaText", "type": "text", "defaultValue": "Learn more" }
    ]
  }'
```

### Auto-added variables

Any `{{identifier}}` referenced in the template body that is **not** declared in
`variableDefinitions` is automatically added as a text variable on save. The response
echoes the added names under `addedVariables` so your client can surface them:

```json theme={null}
{
  "template": {
    "uid": "tmpl_...",
    "engine": "html",
    "variableDefinitions": [
      { "name": "title", "type": "text" },
      { "name": "price", "type": "text" }
    ]
  },
  "addedVariables": ["price"]
}
```

This is what makes the `engine=html` authoring loop feel "just work" — you can type
`{{price}}` into your template and save; the variable appears on the next read
without a separate declaration step.

### `strictVariables` and `jsEnabled`

Two HTML-only toggles affect render behaviour:

<CardGroup cols={2}>
  <Card title="strictVariables" icon="shield">
    When `true`, rendering fails with HTTP 422 if a root-level variable referenced in the
    template was not supplied. Leave off if you rely on `{{#if optional}}` guards.
  </Card>

  <Card title="jsEnabled" icon="code">
    When `true`, scripts inside the template execute during render (Chart.js, KaTeX,
    animated SVG). Off by default to prevent runaway loops. A 30s hard timeout always applies.
  </Card>
</CardGroup>

Both default to `false` and can be flipped with `PUT /templates/{uid}`.

### Helpers and expressions

HTML templates have access to the full Pictify helper library — string casing,
number and currency formatting, date formatting, array helpers, and JSON
inspection. See [Handlebars syntax in Expressions](/concepts/expressions#handlebars-syntax-html-templates) for block syntax and the full helper library.

```html theme={null}
<p>{{titleCase title}}</p>
<p>{{currency price 'USD'}}</p>
<p>{{date publishedAt 'MMM D, YYYY'}}</p>

{{#each items}}
  <li>{{@index}}. {{this.name}} — {{currency this.price 'USD'}}</li>
{{/each}}
```

## FabricJS canvas templates

Set `engine: "fabric"` and pass a FabricJS canvas JSON
object in `fabricJSData`. Multi-page canvases are supported via `pages`.

```bash cURL theme={null}
curl -X POST https://api.pictify.io/templates \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Quote card",
    "engine": "fabric",
    "width": 1080,
    "height": 1080,
    "fabricJSData": { "version": "5.3.0", "objects": [] }
  }'
```

<Note>
  Base64 `data:image/...` sources inside `fabricJSData` are uploaded to Pictify storage
  during save and replaced with CDN URLs. No extra step needed.
</Note>

## Rendering

Once saved, render with [`POST /templates/{uid}/render`](/api-reference/endpoints/templates/render)
and pass variable values in the `variables` object.

```bash cURL theme={null}
curl -X POST https://api.pictify.io/templates/tmpl_abc123/render \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "variables": { "title": "Launch day", "subtitle": "Ship it" },
    "format": "png"
  }'
```


## OpenAPI

````yaml post /templates
openapi: 3.1.0
info:
  title: Pictify API
  version: 1.0.0
  description: |
    Generate images, GIFs, and PDFs from HTML templates programmatically.

    ## Authentication
    All API requests require a Bearer token in the Authorization header:
    ```
    Authorization: Bearer pk_live_your_api_key
    ```

    ## Rate Limits
    - Free: 60 requests/minute
    - Pro: 300 requests/minute
    - Business: 1,000 requests/minute

    Rate limit headers are included in all responses.
  contact:
    email: support@pictify.io
    url: https://pictify.io
  license:
    name: MIT
servers:
  - url: https://api.pictify.io
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Images
    description: Image generation endpoints
  - name: GIFs
    description: GIF generation and capture
  - name: PDFs
    description: PDF generation
  - name: Templates
    description: Template management
  - name: Batch
    description: Batch rendering operations
  - name: Webhooks
    description: Webhook subscription management
  - name: Bindings
    description: Data binding for auto-rendering
paths:
  /templates:
    post:
      tags:
        - Templates
      summary: Create a template
      description: >
        Create a new template. Pictify supports two template engines:


        - `engine: "html"` — Handlebars + HTML. Author a template with
        `{{variable}}` tokens,
          `{{#each}}` / `{{#if}}` blocks, and the built-in helper library. Supplied `html`
          is compile-validated on save; any identifier referenced in the template body
          but missing from `variableDefinitions` is auto-added as a text variable and
          returned in `addedVariables` on the response.
        - `engine: "fabric"` (default) — FabricJS canvas. Provide
        `fabricJSData`.


        If `engine` is omitted the server defaults to `fabric` for backwards
        compatibility.

        New HTML templates should set `engine: "html"` explicitly.
      operationId: createTemplate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  description: Human-readable template name. Shown in the dashboard.
                engine:
                  type: string
                  enum:
                    - fabric
                    - html
                  default: fabric
                  description: >
                    Template engine. Set `html` to author with Handlebars +
                    HTML.
                html:
                  type: string
                  description: >
                    Required for `engine=html`. Handlebars source. Must compile.

                    Undeclared `{{identifier}}` references are auto-added as
                    text variables.
                fabricJSData:
                  type: object
                  description: Required for `engine=fabric`. FabricJS canvas JSON.
                  additionalProperties: true
                width:
                  type: integer
                  description: Render width in px.
                height:
                  type: integer
                  description: Render height in px.
                type:
                  type: string
                  description: >-
                    Template type tag (e.g. `og-image`, `twitter-card`).
                    Free-form.
                category:
                  type: string
                tags:
                  type: array
                  items:
                    type: string
                variableDefinitions:
                  type: array
                  description: >
                    Variable schema. For `engine=html`, identifiers referenced
                    in the template

                    body but not declared here are auto-added as text variables
                    and returned

                    under `addedVariables` in the response.
                  items:
                    $ref: '#/components/schemas/VariableDefinition'
                jsEnabled:
                  type: boolean
                  default: false
                  description: >
                    `engine=html` only. When true, scripts inside the template
                    execute at

                    render time. Enables Chart.js, KaTeX, and animated SVG.
                    Disables

                    infinite-loop protection; the 30s hard timeout still
                    applies.
                strictVariables:
                  type: boolean
                  default: false
                  description: >
                    `engine=html` only. When true, missing root-level variables
                    throw

                    HTTP 422 at render time. Leave off if you rely on `{{#if
                    optional}}` guards.
                outputFormat:
                  type: string
                  enum:
                    - image
                    - pdf
                  default: image
                pdfPreset:
                  type: string
                  enum:
                    - A4
                    - A4_LANDSCAPE
                    - LETTER
                    - LETTER_LANDSCAPE
                    - LEGAL
                    - A3
                    - TABLOID
                  default: A4
                  description: Page preset when `outputFormat=pdf`.
                pages:
                  type: array
                  description: Multi-page canvas pages (`engine=fabric` only).
                  items:
                    type: object
                    properties:
                      pageNumber:
                        type: integer
                      name:
                        type: string
                      fabricJSData:
                        type: object
                        additionalProperties: true
            examples:
              handlebars:
                summary: Handlebars HTML template
                value:
                  name: OG Image
                  engine: html
                  width: 1200
                  height: 630
                  html: >
                    <div
                    style="width:1200px;height:630px;padding:64px;font-family:Inter">
                      <h1 style="font-size:72px">{{title}}</h1>
                      <p style="font-size:32px;color:#6b7280">{{subtitle}}</p>
                      {{#if showCta}}<button>{{ctaText}}</button>{{/if}}
                    </div>
                  variableDefinitions:
                    - name: title
                      type: text
                      defaultValue: Hello world
                    - name: subtitle
                      type: text
                    - name: showCta
                      type: boolean
                      defaultValue: false
                    - name: ctaText
                      type: text
                      defaultValue: Learn more
                  strictVariables: false
                  jsEnabled: false
              fabric:
                summary: FabricJS canvas template
                value:
                  name: Quote card
                  engine: fabric
                  width: 1080
                  height: 1080
                  fabricJSData:
                    version: 5.3.0
                    objects: []
      responses:
        '200':
          description: Template created
          content:
            application/json:
              schema:
                type: object
                properties:
                  template:
                    $ref: '#/components/schemas/Template'
                  addedVariables:
                    type: array
                    description: >
                      `engine=html` only. Names of identifiers referenced in the
                      template

                      body that were auto-added to `variableDefinitions` during
                      save. Omitted

                      when the array would be empty.
                    items:
                      type: string
        '422':
          description: >
            Validation failed. Typical causes for `engine=html`: unclosed
            Handlebars block,

            unknown helper, or (when `strictVariables=true`) a referenced
            variable without

            a definition.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  context:
                    type: object
                    additionalProperties: true
components:
  schemas:
    VariableDefinition:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: Variable identifier. Must match the name used in `{{name}}` tokens.
        type:
          type: string
          enum:
            - text
            - image
            - color
            - chart
            - table
            - array
            - object
          default: text
        defaultValue:
          description: >
            Fallback value when the variable is not supplied at render time.

            Typed according to `type` — string for text/image/color/url, number
            for number,

            boolean for boolean, ISO date string for date, JSON array/object for
            array/object.
        description:
          type: string
        allowRawHtml:
          type: boolean
          description: >
            Only meaningful for `type=text` on `engine=html` templates. When
            true the value

            is NOT HTML-escaped at render time. Use with care — treat as trusted
            input.
          default: false
        validation:
          type: object
          properties:
            required:
              type: boolean
            minLength:
              type: integer
            maxLength:
              type: integer
    Template:
      type: object
      properties:
        uid:
          type: string
        name:
          type: string
        engine:
          type: string
          enum:
            - fabric
            - html
          description: >
            Which renderer owns this template.

            - `fabric` — legacy canvas templates (fabricJSData)

            - `html` — Handlebars + HTML templates (html field, supports
            `{{var}}`, `{{#each}}`, `{{#if}}`, and the built-in helper library)
        html:
          type: string
          description: Handlebars source for `engine=html` templates.
        fabricJSData:
          type: object
          description: FabricJS canvas JSON for `engine=fabric` templates.
          additionalProperties: true
        jsEnabled:
          type: boolean
          description: >
            Only meaningful for `engine=html`. When true, scripts inside the
            template

            execute during render (Chart.js, KaTeX, animated SVG). Off by
            default

            to prevent runaway loops; a 30s hard timeout still applies.
          default: false
        strictVariables:
          type: boolean
          description: >
            Only meaningful for `engine=html`. When true, rendering fails with
            HTTP 422

            if a root-level variable referenced in the template was not
            supplied.

            Leave off if you rely on `{{#if optional}}` guards.
          default: false
        type:
          type: string
        category:
          type: string
        tags:
          type: array
          items:
            type: string
        width:
          type: integer
        height:
          type: integer
        thumbnail:
          type: string
          format: uri
        outputFormat:
          type: string
          enum:
            - image
            - pdf
          default: image
        pdfPreset:
          type: string
          description: Page preset used when `outputFormat=pdf`.
          enum:
            - A4
            - A4_LANDSCAPE
            - LETTER
            - LETTER_LANDSCAPE
            - LEGAL
            - A3
            - TABLOID
          default: A4
        variableDefinitions:
          type: array
          items:
            $ref: '#/components/schemas/VariableDefinition'
        pages:
          type: array
          description: Multi-page canvas pages (fabric engine).
          items:
            type: object
            properties:
              pageNumber:
                type: integer
              name:
                type: string
              fabricJSData:
                type: object
                additionalProperties: true
        layouts:
          type: object
          description: |
            Named layout variants. Keys are short identifiers matching
            `^[a-z0-9-]{1,64}$` (e.g. `twitter-post`, `og-image`). Each value
            overrides `width`, `height`, and renderer-specific data for that
            variant. Limit: 20 layouts per template.
          additionalProperties:
            type: object
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key obtained from the Pictify dashboard

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.