Skip to main content
A Form Template (called a “Flow” in Penbox) defines the structure, appearance, and behavior of forms sent to contacts. This is what you design and build in Penbox Studio - the form builder interface.
For Administrators & Creators: This documentation is for users who design and create form templates. If you just need to send forms to contacts, see Forms.

Understanding Form Templates

A Form Template is the blueprint for your forms. It defines:
  • Form structure: Steps, fields, and validation
  • Portal experience: Welcome page, form pages, confirmation page
  • Notifications: Invitations, reminders, completion emails
  • Automations: Actions triggered when forms are submitted
  • Appearance: Branding, layout, and styling
  • Behavior: Conditional logic, calculations, integrations

Template Versioning

Form Templates support versioning, which allows you to iterate on designs while keeping existing forms stable.

How Versioning Works

  1. Create a template - Starts as version 1
  2. Make changes - Edit in draft mode
  3. Publish version - Lock this version for use
  4. Create new version - Continue iterating
  5. Publish when ready - New forms use latest published version

Version Properties

  • Version number: Auto-incremented integer (1, 2, 3…)
  • Published status: Published versions can be used in Form Presets
  • Deprecated status: Mark old versions as deprecated
  • Active version: Form Presets link to latest published version by default
Existing forms always use the version they were created with. Publishing a new version doesn’t change existing forms - only newly created forms use the new version.

Template Structure

Basic Information

FieldDescriptionRequired
NameTemplate identifier (max 64 chars)Yes
SlugURL-friendly identifierAuto-generated
VersionVersion numberAuto
LocaleDefault language (2-char code)Yes
DescriptionWhat this template is for (max 1000 chars)No

Multi-Language Support

Templates support multiple languages through the locales and strings configuration: Locales Array
["en", "fr", "es", "de"]
Strings Object
{
  "en": {
    "welcome_title": "Welcome",
    "submit_button": "Submit"
  },
  "fr": {
    "welcome_title": "Bienvenue",
    "submit_button": "Soumettre"
  }
}
Users can switch languages in the portal, and all text will update accordingly.

Portal Pages

Form templates include three main portal pages that contacts see:

1. Welcome Page

The first page contacts see when opening the form. Configuration options:
{
  "welcome": {
    "enabled": true,
    "options": {
      "image": "cdn://pen-fill/hello.svg",
      "title": "Hello",
      "message": "<p>Please use this secure form to provide the required data</p>",
      "start-button": "Let's get started",
      "help-text": "Need help?",
      "show-help-button": true,
      "show-privacy-policy": true,
      "custom-privacy-policy": ""
    }
  }
}
Customizable elements:
  • Header image
  • Title text
  • Welcome message (HTML supported)
  • Start button text
  • Help button and text
  • Privacy policy link
A welcoming, clear welcome page increases completion rates. Explain what the form is for, how long it takes, and why you need the information.

2. Submit (Review) Page

Shown after all form steps are completed, before final submission. Configuration options:
{
  "submit": {
    "enabled": true,
    "options": {
      "valid-image": "cdn://pen-fill/one_last_thing.svg",
      "valid-title": "Send your responses!",
      "valid-message": "Please click Send to complete.",
      "valid-submit-button": "Send",
      "valid-modify-button": "Modify",
      "valid-confirmation-message": "By sending, you confirm the information is correct.",
      "invalid-image": "cdn://pen-fill/one_last_thing.svg",
      "invalid-title": "Your responses are incomplete!",
      "invalid-message": "We still need some information from you.",
      "invalid-button": "Back to the form"
    }
  }
}
Customizable elements:
  • Images for valid/invalid states
  • Titles for valid/invalid states
  • Messages and instructions
  • Button text
  • Confirmation message

3. Ending Page

Shown after successful form submission. Configuration options:
{
  "ending": {
    "enabled": true,
    "options": {
      "image": "cdn://pen-fill/ended.svg",
      "title": "Your answers are being treated!",
      "message": "You can now close this window.",
      "rate-ux": true,
      "redirect-url": ""
    }
  }
}
Customizable elements:
  • Confirmation image
  • Thank you title
  • Closing message
  • UX rating widget (optional)
  • Redirect URL (optional - redirect after N seconds)

Form Steps

The core of your template is the form itself, composed of steps and elements.

Creating Steps

Each step is a page in the form. Steps contain elements (fields) that collect data. Step structure:
{
  "id": "step_1",
  "label": "Company Information",
  "enable": true,
  "elements": [
    // Elements go here
  ]
}
Step properties:
  • id: Unique identifier (required)
  • label: Step name shown to users
  • enable: Show/hide the step (can use conditional logic)
  • elements: Array of form elements
Every step must contain at least one element with "type": "submit" or it won’t be submittable. Alternatively, use elements with submit_on_change enabled.

Conditional Steps

Use JSON expressions to show/hide steps based on data:
{
  "id": "business_details",
  "label": "Business Details",
  ":if": "{data.account_type} === 'business'",
  "elements": [...]
}
The step only appears if the condition evaluates to true.

Form Elements

Elements are the building blocks of your form - the actual input fields and content.

Element Structure

{
  "id": "company_name",
  "key": "company_name",
  "type": "text",
  "title": "Company Name",
  "required": true,
  "help": "Legal name of your company",
  "placeholder": "Acme Corporation"
}

Common Element Properties

PropertyDescriptionRequired
idUnique identifier within stepAuto (from key or type)
keyData storage keyRecommended
typeElement typeYes
titleLabel shown to userNo
requiredMust be filledNo (default: false)
helpHelp textNo
placeholderPlaceholder textNo

Element Types

No data collection - for display only
  • card: Content card with title and text
  • image: Display an image
  • paragraph: Text content block
Example:
{
  "type": "paragraph",
  "title": "Important Information",
  "text": "Please ensure all information is accurate."
}
Type: textSingle-line or multi-line text input.
{
  "key": "description",
  "type": "text",
  "title": "Description",
  "multiline": true,
  "rows": 5,
  "maxlength": 500
}
Options:
  • multiline: Enable textarea
  • rows: Number of rows (for textarea)
  • maxlength: Character limit
  • pattern: Regex validation
Type: checkboxSingle checkbox for yes/no or agreement.
{
  "key": "terms_accepted",
  "type": "checkbox",
  "title": "I agree to the terms and conditions",
  "required": true
}
Type: checkboxesMultiple options with checkboxes.
{
  "key": "services",
  "type": "checkboxes",
  "title": "Select services you're interested in",
  "options": [
    { "value": "consulting", "label": "Consulting" },
    { "value": "development", "label": "Development" },
    { "value": "support", "label": "Support" }
  ],
  "min": 1,
  "max": 3
}
Type: radio or autocompleteSingle selection from multiple options.
{
  "key": "country",
  "type": "autocomplete",
  "title": "Country",
  "options": [
    { "value": "US", "label": "United States" },
    { "value": "UK", "label": "United Kingdom" },
    { "value": "FR", "label": "France" }
  ],
  "searchable": true
}
Type: date or datetimeDate picker for selecting dates.
{
  "key": "birth_date",
  "type": "date",
  "title": "Date of Birth",
  "min": "1900-01-01",
  "max": "today",
  "format": "YYYY-MM-DD"
}
Type: fileFile upload field.
{
  "key": "documents",
  "type": "file",
  "title": "Upload Documents",
  "accept": [".pdf", ".jpg", ".png"],
  "multiple": true,
  "maxFiles": 5,
  "maxSize": 10485760
}
Options:
  • accept: Allowed file types
  • multiple: Allow multiple files
  • maxFiles: Maximum number of files
  • maxSize: Maximum file size in bytes
Type: ratingStar or numeric rating input.
{
  "key": "satisfaction",
  "type": "rating",
  "title": "How satisfied are you?",
  "max": 5,
  "icon": "star"
}
Type: toggleSwitch/toggle input.
{
  "key": "newsletter",
  "type": "toggle",
  "title": "Subscribe to newsletter",
  "default": false
}
Type: hiddenStore data without displaying to user.
{
  "key": "source",
  "type": "hidden",
  "value": "email_campaign"
}
Type: submitButton to submit the step.
{
  "type": "submit",
  "label": "Next",
  "align": "right"
}

Conditional Elements

Show/hide elements based on other field values:
{
  "key": "company_registration",
  "type": "text",
  "title": "Company Registration Number",
  ":if": "{data.account_type} === 'business'"
}

Variables

Variables allow you to define global values, static or computed, accessible throughout the form.

Defining Variables

Object format (no dependencies):
{
  "variables": {
    "company_email": "[email protected]",
    "max_upload_size": 10485760
  }
}
Array format (with dependencies):
{
  "variables": [
    { "base_price": 100 },
    { "tax_rate": 0.2 },
    { "total_price": "{base_price} * (1 + {tax_rate})" }
  ]
}

Using Variables

Reference variables anywhere in the form using {variable_name}:
{
  "type": "paragraph",
  "text": "For support, contact us at {company_email}"
}
Do not use user, data, or anything starting with $ as variable names - these are reserved.

Automations

Automations are actions that trigger automatically based on form events.

Automation Structure

{
  "automations": [
    {
      "id": "uuid",
      "name": "Send confirmation email",
      "delay": 0,
      "icon": "envelope",
      "on": ["responses:completed"],
      "actions": [
        {
          "type": "email",
          "config": {
            "to": "{user.email}",
            "subject": "Thank you for your submission",
            "body": "We received your information..."
          }
        }
      ]
    }
  ]
}

Automation Triggers

Available event triggers:
  • responses:created - Form response is created (draft)
  • responses:updated - Form response is updated
  • responses:completed - Form is completed/submitted
  • responses:declined - Form is declined
  • requests:expired - Form expires without completion
  • manual - Triggered manually by team member

Automation Actions

Send an email.
{
  "type": "email",
  "config": {
    "to": "{user.email}",
    "cc": ["[email protected]"],
    "subject": "Your submission",
    "body": "Thank you, {user.given_name}...",
    "from": "[email protected]"
  }
}
Available in email content:
  • Form data: {data.field_key}
  • User info: {user.email}, {user.given_name}, etc.
  • Form reference: {reference}
  • Variables: {variable_name}

Automation Delays

Add delays before triggering automations:
{
  "delay": 1440,  // 24 hours in minutes
  "name": "Send reminder if not completed",
  "on": ["responses:created"],
  "actions": [...]
}

Notifications

Notifications are emails sent to contacts about the form itself (not from automations).

Notification Types

To Contact:
  • Invitations: When form is sent
  • Reminders: If form not completed
  • Confirmation: When form is submitted
To Team:
  • On submission: Notify team when form completed
  • On bounce: Notify if email bounces

Notification Configuration

{
  "notifications": [
    {
      "type": "email",
      "to": [
        { "email": "[email protected]" },
        { "role": "owner" }
      ],
      "on": ["responses:completed"]
    }
  ]
}

Invitation Template

Configure the invitation email template:
{
  "invitations": {
    "subject": "Action required: Complete your information",
    "body": "Please complete the form at {link}",
    "reminders": {
      "count": 3,
      "interval": 2,
      "unit": "days"
    }
  }
}

Publishing Templates

Publish Process

  1. Create and test your template
  2. Validate all steps and elements work correctly
  3. Set published: true
  4. Template version is locked
  5. Can now be used in Form Presets

Template Validation

Before publishing, ensure:
  • All steps have submit buttons or auto-submit elements
  • Required fields are clearly marked
  • Conditional logic works as expected
  • All images and assets load
  • Multi-language strings are complete (if using)
  • Automations are correctly configured
  • Test submission works end-to-end

Best Practices

Most contacts will complete forms on mobile devices. Test your forms on small screens and ensure they’re easy to use.
Only ask for information you truly need. Each additional field decreases completion rates.
Break long forms into logical steps, but don’t create too many steps. 3-5 steps is usually optimal.
Use the help property to explain what you need. Especially important for complex or uncommon fields.
Always test the complete form flow before publishing. Submit test data and verify automations work.
Only show fields that are relevant. This keeps forms clean and improves completion rates.
Always send a confirmation when forms are completed. This builds trust and provides a receipt.
Don’t create new versions for small changes. Batch changes together to avoid version sprawl.

Next Steps