Collecting data

Collecting Data with Penneo Collect API

This guide provides practical examples of creating forms using the Penneo Collect API. Each example demonstrates different features and field types to help you build flexible, intelligent forms for your use cases.

Table of Contents


Getting Started

All examples use the base endpoint:

POST https://app.penneo.com/collect/api/v1/forms

A JWT token is required via the header: Authorization: Bearer <token>. See the Authentication Guide for how to authenticate and retrieve the token.


Example 1: Simple Contact Form

A basic contact form collecting name, email, and phone number. This example shows automatic primary signer details mapping, saving time for form fillers.

{
  "name": "Contact Information",
  "language": "EN",
  "description": "Please provide your contact information",
  "sections": [
    {
      "title": "Your Details",
      "description": "We'll use this information to contact you",
      "fields": [
        {
          "type": "TEXT",
          "label": "Full Name",
          "required": true,
          "mapTo": "primarySigner.name",
          "validations": {
            "maxLength": 100
          }
        },
        {
          "type": "EMAIL",
          "label": "Email Address",
          "required": true,
          "mapTo": "primarySigner.email"
        },
        {
          "type": "PHONE",
          "label": "Phone Number",
          "required": true,
          "countryOptions": ["DK", "NO", "SE", "DE", "GB"]
        }
      ]
    }
  ]
}

Key Features:

  • Automatic Primary Signer Mapping: The mapTo property automatically uses entered name and email to identify the form filler
  • Country Selection: Phone field allows users to select their country code
  • Validation: Email automatically validates format, maxLength prevents excessively long inputs

Example 2: Employee Onboarding Form

A comprehensive employee onboarding form demonstrating text fields, dates, choices, and formatted instructions.

{
  "name": "Employee Onboarding",
  "language": "EN",
  "description": "New Employee Information Collection",
  "sections": [
    {
      "title": "Welcome",
      "fields": [
        {
          "type": "HTML",
          "content": "<p><strong>Welcome to Our Company!</strong></p><p>Please complete this form to begin your onboarding process. All fields marked as required must be completed.</p><ul><li>Ensure all information is accurate</li><li>Your manager will be notified upon submission</li><li>You'll receive a copy via email</li></ul>"
        }
      ]
    },
    {
      "title": "Personal Information",
      "description": "Your basic details",
      "fields": [
        {
          "type": "TEXT",
          "label": "Full Name",
          "required": true,
          "mapTo": "primarySigner.name"
        },
        {
          "type": "EMAIL",
          "label": "Personal Email",
          "required": true,
          "mapTo": "primarySigner.email"
        },
        {
          "type": "DATE",
          "label": "Date of Birth",
          "required": true,
          "validations": {
            "dateFormat": "dd/MM/yyyy"
          }
        },
        {
          "type": "NIN",
          "label": "National ID Number",
          "required": true,
          "countryCodes": ["DK", "NO", "SE"]
        }
      ]
    },
    {
      "title": "Employment Details",
      "fields": [
        {
          "type": "TEXT",
          "label": "Position Title",
          "required": true
        },
        {
          "type": "CHOICE",
          "label": "Department",
          "required": true,
          "layout": "SELECT",
          "options": [
            {
              "label": "Engineering",
              "value": "engineering"
            },
            {
              "label": "Sales",
              "value": "sales"
            },
            {
              "label": "Marketing",
              "value": "marketing"
            },
            {
              "label": "Finance",
              "value": "finance"
            },
            {
              "label": "Human Resources",
              "value": "hr"
            }
          ]
        },
        {
          "type": "DATE",
          "label": "Start Date",
          "required": true,
          "validations": {
            "dateFormat": "yyyy-MM-dd"
          }
        },
        {
          "type": "CHOICE",
          "label": "Employment Type",
          "required": true,
          "layout": "RADIO",
          "options": [
            {
              "label": "Full-time",
              "value": "fulltime"
            },
            {
              "label": "Part-time",
              "value": "parttime"
            },
            {
              "label": "Contract",
              "value": "contract"
            }
          ]
        }
      ]
    },
    {
      "title": "Emergency Contact",
      "fields": [
        {
          "type": "TEXT",
          "label": "Emergency Contact Name",
          "required": true
        },
        {
          "type": "TEXT",
          "label": "Relationship",
          "required": true
        },
        {
          "type": "PHONE",
          "label": "Emergency Contact Phone",
          "required": true,
          "countryOptions": ["DK", "NO", "SE", "DE", "GB", "US"]
        }
      ]
    },
    {
      "title": "Agreement",
      "fields": [
        {
          "type": "CHOICE",
          "label": "I agree to the following",
          "required": true,
          "layout": "CHECKBOX",
          "options": [
            {
              "label": "Company Code of Conduct",
              "value": "code_of_conduct"
            },
            {
              "label": "Privacy Policy",
              "value": "privacy_policy"
            },
            {
              "label": "IT Usage Policy",
              "value": "it_policy"
            }
          ]
        }
      ]
    }
  ],
  "predefinedSigners": [
    {
      "fullName": "HR Department",
      "email": "[email protected]"
    }
  ]
}

Key Features:

  • HTML Field: Provides formatted welcome instructions with lists (only <p>, <em>, <strong>, <ul>, and <li> tags are allowed for now)
  • National ID Validation: Validates format for Danish, Norwegian, or Swedish national IDs
  • Multiple Choice Layouts: Demonstrates dropdown (SELECT), radio buttons (RADIO), and checkboxes (CHECKBOX)
  • Date Formatting: Shows different date format options
  • Predefined Signers: HR department automatically added as a signer

Example 3: Rental Agreement Form with Multiple Signers

This form demonstrates the powerful additional signers feature, requiring a guarantor and allowing optional co-tenants.

{
  "name": "Residential Rental Agreement",
  "language": "EN",
  "description": "Rental application and lease agreement",
  "sections": [
    {
      "title": "Primary Tenant Information",
      "fields": [
        {
          "type": "TEXT",
          "label": "Full Name",
          "required": true,
          "mapTo": "primarySigner.name"
        },
        {
          "type": "EMAIL",
          "label": "Email Address",
          "required": true,
          "mapTo": "primarySigner.email"
        },
        {
          "type": "PHONE",
          "label": "Phone Number",
          "required": true,
          "countryOptions": ["DK", "NO", "SE"]
        },
        {
          "type": "DATE",
          "label": "Date of Birth",
          "required": true,
          "validations": {
            "dateFormat": "dd/MM/yyyy"
          }
        },
        {
          "type": "NIN",
          "label": "National ID",
          "required": true,
          "countryCodes": ["DK", "NO", "SE"]
        }
      ]
    },
    {
      "title": "Current Address",
      "fields": [
        {
          "type": "TEXT",
          "label": "Street Address",
          "required": true
        },
        {
          "type": "TEXT",
          "label": "City",
          "required": true
        },
        {
          "type": "TEXT",
          "label": "Postal Code",
          "required": true,
          "validations": {
            "maxLength": 10
          }
        }
      ]
    },
    {
      "title": "Employment Information",
      "fields": [
        {
          "type": "TEXT",
          "label": "Employer Name",
          "required": true
        },
        {
          "type": "TEXT",
          "label": "Position",
          "required": true
        },
        {
          "type": "NUMBER",
          "label": "Monthly Income (DKK)",
          "required": true,
          "validations": {
            "min": 0,
            "allowDecimals": true
          }
        }
      ]
    },
    {
      "title": "Rental Property Details",
      "fields": [
        {
          "type": "TEXT",
          "label": "Property Address",
          "required": true
        },
        {
          "type": "DATE",
          "label": "Desired Move-in Date",
          "required": true,
          "validations": {
            "dateFormat": "yyyy-MM-dd"
          }
        },
        {
          "type": "NUMBER",
          "label": "Lease Duration (months)",
          "required": true,
          "validations": {
            "min": 6,
            "max": 36
          }
        }
      ]
    },
    {
      "title": "Additional Information",
      "fields": [
        {
          "type": "TEXT",
          "label": "Additional Comments",
          "required": false,
          "multiline": true
        }
      ]
    }
  ],
  "additionalSignersConfig": {
    "enabled": true,
    "max": 4,
    "slots": [
      {
        "title": "Guarantor",
        "description": "A guarantor is required for this rental agreement. This person agrees to be responsible for rent payments if you are unable to pay.",
        "required": true
      },
      {
        "title": "Co-Tenant",
        "description": "If you plan to share this rental with another person, add them as a co-tenant. They will also sign the lease agreement.",
        "required": false
      },
      {
        "title": "Additional Co-Tenant",
        "description": "Add another co-tenant if needed.",
        "required": false
      }
    ]
  },
  "predefinedSigners": [
    {
      "fullName": "Property Management",
      "email": "[email protected]"
    }
  ]
}

Key Features:

  • Automatic Primary Signer: Name and email mapped to identify the primary tenant
  • Required Additional Signer: Guarantor is mandatory with clear description
  • Optional Additional Signers: Allows up to 2 optional co-tenants
  • Maximum Signers Control: Limits total additional signers to 4 (including required + optional slots)
  • Multiline Text: Comments field uses textarea for longer responses
  • Number Validation: Income and lease duration have min/max constraints

Example 4: Business Registration Form

A complex business form showing business ID validation, various field types, and structured data collection.

{
  "name": "Business Registration Application",
  "language": "EN",
  "sections": [
    {
      "title": "Instructions",
      "fields": [
        {
          "type": "HTML",
          "content": "<p><strong>Business Registration</strong></p><p>Complete this form to register your business. You'll need:</p><ul><li>Your business registration number</li><li>Company financial information</li><li>Authorized signatory details</li></ul><p><strong>Note:</strong> All information will be verified before approval.</p>"
        }
      ]
    },
    {
      "title": "Company Information",
      "fields": [
        {
          "type": "TEXT",
          "label": "Company Legal Name",
          "required": true,
          "validations": {
            "maxLength": 200
          }
        },
        {
          "type": "BUSINESS_ID",
          "label": "Business Registration Number",
          "required": true,
          "countryCodes": ["DK", "NO", "SE", "BE"]
        },
        {
          "type": "TEXT",
          "label": "Trading Name (if different)",
          "required": false
        },
        {
          "type": "DATE",
          "label": "Date of Incorporation",
          "required": true,
          "validations": {
            "dateFormat": "dd/MM/yyyy"
          }
        },
        {
          "type": "CHOICE",
          "label": "Business Type",
          "required": true,
          "layout": "SELECT",
          "options": [
            {
              "label": "Sole Proprietorship",
              "value": "sole_proprietorship"
            },
            {
              "label": "Partnership",
              "value": "partnership"
            },
            {
              "label": "Limited Liability Company (ApS/AS)",
              "value": "llc"
            },
            {
              "label": "Public Limited Company (A/S)",
              "value": "plc"
            },
            {
              "label": "Other",
              "value": "other"
            }
          ]
        }
      ]
    },
    {
      "title": "Business Address",
      "description": "Principal place of business",
      "fields": [
        {
          "type": "TEXT",
          "label": "Street Address",
          "required": true
        },
        {
          "type": "TEXT",
          "label": "City",
          "required": true
        },
        {
          "type": "TEXT",
          "label": "Postal Code",
          "required": true
        },
        {
          "type": "CHOICE",
          "label": "Country",
          "required": true,
          "layout": "SELECT",
          "options": [
            {
              "label": "Denmark",
              "value": "DK"
            },
            {
              "label": "Norway",
              "value": "NO"
            },
            {
              "label": "Sweden",
              "value": "SE"
            },
            {
              "label": "Belgium",
              "value": "BE"
            }
          ]
        }
      ]
    },
    {
      "title": "Contact Information",
      "fields": [
        {
          "type": "EMAIL",
          "label": "Company Email",
          "required": true
        },
        {
          "type": "PHONE",
          "label": "Company Phone",
          "required": true,
          "countryOptions": ["DK", "NO", "SE", "BE"]
        },
        {
          "type": "TEXT",
          "label": "Website",
          "required": false
        }
      ]
    },
    {
      "title": "Financial Information",
      "fields": [
        {
          "type": "NUMBER",
          "label": "Annual Revenue (EUR)",
          "required": true,
          "validations": {
            "min": 0,
            "allowDecimals": true
          }
        },
        {
          "type": "NUMBER",
          "label": "Number of Employees",
          "required": true,
          "validations": {
            "min": 0,
            "max": 1000000
          }
        },
        {
          "type": "CHOICE",
          "label": "Industry Sector",
          "required": true,
          "layout": "SELECT",
          "options": [
            {
              "label": "Technology",
              "value": "technology"
            },
            {
              "label": "Finance",
              "value": "finance"
            },
            {
              "label": "Healthcare",
              "value": "healthcare"
            },
            {
              "label": "Manufacturing",
              "value": "manufacturing"
            },
            {
              "label": "Retail",
              "value": "retail"
            },
            {
              "label": "Services",
              "value": "services"
            },
            {
              "label": "Other",
              "value": "other"
            }
          ]
        }
      ]
    },
    {
      "title": "Authorized Signatory",
      "description": "Person authorized to sign on behalf of the company",
      "fields": [
        {
          "type": "TEXT",
          "label": "Full Name",
          "required": true,
          "mapTo": "primarySigner.name"
        },
        {
          "type": "EMAIL",
          "label": "Email Address",
          "required": true,
          "mapTo": "primarySigner.email"
        },
        {
          "type": "TEXT",
          "label": "Position/Title",
          "required": true
        },
        {
          "type": "NIN",
          "label": "National ID",
          "required": true,
          "countryCodes": ["DK", "NO", "SE", "BE"]
        },
        {
          "type": "PHONE",
          "label": "Mobile Phone",
          "required": true,
          "countryOptions": ["DK", "NO", "SE", "BE"]
        }
      ]
    },
    {
      "title": "Terms and Conditions",
      "fields": [
        {
          "type": "HTML",
          "content": "<p>By submitting this form, you confirm that:</p><ul><li>All information provided is true and accurate</li><li>You have authority to represent the company</li><li>You agree to our terms of service</li></ul>"
        },
        {
          "type": "CHOICE",
          "label": "Confirmations",
          "required": true,
          "layout": "CHECKBOX",
          "options": [
            {
              "label": "I confirm all information is accurate",
              "value": "accuracy"
            },
            {
              "label": "I have authority to sign on behalf of the company",
              "value": "authority"
            },
            {
              "label": "I agree to the Terms of Service",
              "value": "terms"
            }
          ]
        }
      ]
    }
  ]
}

Key Features:

  • Business ID Validation: Validates business registration numbers for different countries
  • Decimal Numbers: Revenue field allows decimal values
  • Range Validation: Employee count has realistic bounds
  • Structured Sections: Logical grouping of related information
  • HTML Instructions: Clear guidance throughout the form (only <p>, <em>, <strong>, <ul>, and <li> tags are allowed)
  • Multiple Validation Types: Combines maxLength, min/max, and format validations

Example 5: Survey Form with Various Field Types

A comprehensive survey demonstrating all available field types and validation options.

{
    "name": "Customer Satisfaction Survey",
    "language": "EN",
    "description": "Help us improve our services",
    "sections": [
        {
            "title": "Introduction",
            "fields": [
                {
                    "type": "HTML",
                    "content": "<p><strong>Thank you for your feedback!</strong></p><p>This survey will take approximately 5 minutes to complete. Your responses will help us improve our services.</p>"
                }
            ]
        },
        {
            "title": "Your Information",
            "fields": [
                {
                    "type": "TEXT",
                    "label": "Name",
                    "required": true,
                    "mapTo": "primarySigner.name"
                },
                {
                    "type": "EMAIL",
                    "label": "Email",
                    "required": true,
                    "mapTo": "primarySigner.email"
                },
                {
                    "type": "CHOICE",
                    "label": "How did you hear about us?",
                    "required": true,
                    "layout": "RADIO",
                    "options": [
                        {
                            "label": "Online search",
                            "value": "search"
                        },
                        {
                            "label": "Social media",
                            "value": "social"
                        },
                        {
                            "label": "Friend or colleague",
                            "value": "referral"
                        },
                        {
                            "label": "Advertisement",
                            "value": "ad"
                        },
                        {
                            "label": "Other",
                            "value": "other"
                        }
                    ]
                }
            ]
        },
        {
            "title": "Service Experience",
            "fields": [
                {
                    "type": "CHOICE",
                    "label": "Overall satisfaction",
                    "required": true,
                    "layout": "RADIO",
                    "options": [
                        {
                            "label": "Very Satisfied",
                            "value": "5"
                        },
                        {
                            "label": "Satisfied",
                            "value": "4"
                        },
                        {
                            "label": "Neutral",
                            "value": "3"
                        },
                        {
                            "label": "Dissatisfied",
                            "value": "2"
                        },
                        {
                            "label": "Very Dissatisfied",
                            "value": "1"
                        }
                    ]
                },
                {
                    "type": "HTML",
                    "content": "<p>Which aspects did you find most valuable?</p>"
                },
                {
                    "type": "CHOICE",
                    "label": "Valuable Aspects",
                    "required": false,
                    "layout": "CHECKBOX",
                    "options": [
                        {
                            "label": "Easy to use",
                            "value": "usability"
                        },
                        {
                            "label": "Fast response times",
                            "value": "speed"
                        },
                        {
                            "label": "Helpful customer support",
                            "value": "support"
                        },
                        {
                            "label": "Good value for money",
                            "value": "value"
                        },
                        {
                            "label": "Comprehensive features",
                            "value": "features"
                        }
                    ]
                },
                {
                    "type": "TEXT",
                    "label": "What could we improve?",
                    "required": false,
                    "multiline": true
                }
            ]
        },
        {
            "title": "Product Usage",
            "fields": [
                {
                    "type": "HTML",
                    "content": "<p>How many times per week do you use our service?</p>"
                },
                {
                    "type": "NUMBER",
                    "label": "Weekly Usage",
                    "required": true,
                    "validations": {
                        "min": 0,
                        "max": 100
                    }
                },
                {
                    "type": "HTML",
                    "content": "<p>When did you first start using our service?</p>"
                },
                {
                    "type": "DATE",
                    "label": "Start Date",
                    "required": false,
                    "validations": {
                        "dateFormat": "MM/yyyy"
                    }
                },
                {
                    "type": "CHOICE",
                    "label": "Would you recommend us to others?",
                    "required": true,
                    "layout": "RADIO",
                    "options": [
                        {
                            "label": "Definitely",
                            "value": "definitely"
                        },
                        {
                            "label": "Probably",
                            "value": "probably"
                        },
                        {
                            "label": "Not sure",
                            "value": "unsure"
                        },
                        {
                            "label": "Probably not",
                            "value": "probably_not"
                        },
                        {
                            "label": "Definitely not",
                            "value": "definitely_not"
                        }
                    ]
                }
            ]
        },
        {
            "title": "Additional Feedback",
            "fields": [
                {
                    "type": "TEXT",
                    "label": "Any other comments or suggestions?",
                    "required": false,
                    "multiline": true
                },
                {
                    "type": "CHOICE",
                    "label": "May we contact you about your feedback?",
                    "required": true,
                    "layout": "RADIO",
                    "options": [
                        {
                            "label": "Yes, please contact me",
                            "value": "yes"
                        },
                        {
                            "label": "No, thank you",
                            "value": "no"
                        }
                    ]
                }
            ]
        }
    ]
}

Key Features:

  • Rating Scales: Radio buttons used for satisfaction ratings
  • Multiple Selection: Checkboxes allow selecting multiple valuable aspects
  • Text Areas: Multiline fields for detailed feedback
  • Number Ranges: Usage frequency with reasonable bounds
  • Optional Fields: Many fields are optional to reduce friction
  • Clear Purpose: HTML introduction explains the survey's purpose (only <p>, <em>, <strong>, <ul>, and <li> tags are allowed)

Example 6: Multi-Language Form

The same form in different languages to demonstrate internationalization.

Danish Version

{
  "name": "Kontaktformular",
  "language": "DA",
  "description": "Venligst udfyld dine kontaktoplysninger",
  "sections": [
    {
      "title": "Dine oplysninger",
      "description": "Vi bruger disse oplysninger til at kontakte dig",
      "fields": [
        {
          "type": "TEXT",
          "label": "Fulde navn",
          "required": true,
          "mapTo": "primarySigner.name"
        },
        {
          "type": "EMAIL",
          "label": "E-mailadresse",
          "required": true,
          "mapTo": "primarySigner.email"
        },
        {
          "type": "PHONE",
          "label": "Telefonnummer",
          "required": true,
          "countryOptions": ["DK", "NO", "SE"]
        },
        {
          "type": "TEXT",
          "label": "Besked",
          "required": false,
          "multiline": true
        }
      ]
    }
  ]
}

Norwegian Version

{
  "name": "Kontaktskjema",
  "language": "NO",
  "description": "Vennligst fyll ut kontaktinformasjonen din",
  "sections": [
    {
      "title": "Dine opplysninger",
      "description": "Vi bruker denne informasjonen til å kontakte deg",
      "fields": [
        {
          "type": "TEXT",
          "label": "Fullt navn",
          "required": true,
          "mapTo": "primarySigner.name"
        },
        {
          "type": "EMAIL",
          "label": "E-postadresse",
          "required": true,
          "mapTo": "primarySigner.email"
        },
        {
          "type": "PHONE",
          "label": "Telefonnummer",
          "required": true,
          "countryOptions": ["NO", "SE", "DK"]
        },
        {
          "type": "TEXT",
          "label": "Melding",
          "required": false,
          "multiline": true
        }
      ]
    }
  ]
}

Supported Languages:

  • DA (Danish)
  • DE (German)
  • EN (English)
  • FI (Finnish)
  • FR (French)
  • NL (Dutch)
  • NO (Norwegian)
  • SV (Swedish)

What the Language Setting Controls: When you set the language field on a form:

  • Email Language: Determines the language of notification emails sent to end users
  • Signing Page Language: Sets the default language for the signing page interface
  • User Control: End users can change the language on the signing page if needed

Example 7: Using Merge Fields in HTML Content

Merge fields allow you to reference previously entered form data within HTML content fields. This is useful for creating personalized summaries, confirmation messages, or dynamic instructions based on user input.

Syntax

Use double curly braces with the field key: {{fieldKey}}

The field key format is: <type>_<CamelCaseLabel>_<SectionIndex> Note that you can also define your own field key value, so you can add merge fields when creating your form. You don't need to wait for the fieldKey to be generated after the form has been created.

For example:

  • {{text_FullName_0}} - References a text field labeled "Full Name" in section 0
  • {{email_Email_0}} - References an email field in section 0
  • {{choice_Department_1}} - References a choice field in section 1

Example: Loan Application with Summary

This example collects applicant information and uses merge fields to display a personalized confirmation summary.

{
  "name": "Loan Application",
  "language": "EN",
  "description": "Apply for a personal loan",
  "sections": [
    {
      "title": "Personal Information",
      "fields": [
        {
          "type": "TEXT",
          "label": "Full Name",
          "required": true,
          "mapTo": "primarySigner.name"
        },
        {
          "type": "EMAIL",
          "label": "Email",
          "required": true,
          "mapTo": "primarySigner.email"
        },
        {
          "type": "PHONE",
          "label": "Phone",
          "required": true,
          "countryOptions": ["DK", "NO", "SE"]
        }
      ]
    },
    {
      "title": "Loan Details",
      "fields": [
        {
          "type": "NUMBER",
          "label": "Loan Amount",
          "required": true,
          "validations": {
            "min": 10000,
            "max": 500000
          }
        },
        {
          "type": "CHOICE",
          "label": "Loan Purpose",
          "required": true,
          "layout": "SELECT",
          "options": [
            {
              "label": "Home Improvement",
              "value": "home_improvement"
            },
            {
              "label": "Vehicle Purchase",
              "value": "vehicle"
            },
            {
              "label": "Debt Consolidation",
              "value": "debt_consolidation"
            },
            {
              "label": "Education",
              "value": "education"
            },
            {
              "label": "Other",
              "value": "other"
            }
          ]
        },
        {
          "type": "CHOICE",
          "label": "Repayment Period",
          "required": true,
          "layout": "RADIO",
          "options": [
            {
              "label": "12 months",
              "value": "12"
            },
            {
              "label": "24 months",
              "value": "24"
            },
            {
              "label": "36 months",
              "value": "36"
            },
            {
              "label": "48 months",
              "value": "48"
            }
          ]
        }
      ]
    },
    {
      "title": "Application Summary",
      "fields": [
        {
          "type": "HTML",
          "content": "<p><strong>Please review your application details:</strong></p><p>Applicant: <strong>{{text_FullName_0}}</strong></p><p>Email: {{email_Email_0}}</p><p>Requested Amount: {{number_LoanAmount_1}} DKK</p><p>Purpose: {{choice_LoanPurpose_1}}</p><p>Repayment Period: {{choice_RepaymentPeriod_1}} months</p><p><em>By signing below, you confirm that all information provided is accurate.</em></p>"
        }
      ]
    }
  ],
  "predefinedSigners": [
    {
      "fullName": "Loan Department",
      "email": "[email protected]"
    }
  ]
}

Key Features:

  • Dynamic Summary: The HTML field in section 2 uses merge fields to display a summary of data entered in sections 0 and 1
  • Field References: Each {{...}} placeholder gets replaced with the actual value entered by the user
  • Personalized Experience: Users see their own information reflected back, reducing errors and building confidence
  • PDF Output: Merge fields are also resolved when generating the signed PDF document

Merge Field Reference by Type:

Field TypeExample KeyNotes
TEXT{{text_FullName_0}}Returns the entered text
EMAIL{{email_Email_0}}Returns the email address
PHONE{{phone_Phone_0}}Returns the phone number
NUMBER{{number_Amount_1}}Returns the numeric value
DATE{{date_StartDate_1}}Returns the formatted date
CHOICE{{choice_Option_1}}Returns the selected value
NIN{{nin_NationalId_0}}Returns the national ID
BUSINESS_ID{{businessid_BusinessNumber_0}}Returns the business ID

Tips for Using Merge Fields:

  • Merge fields only work within HTML field content
  • If a referenced field hasn't been filled in yet, the placeholder remains visible
  • Field keys are case-sensitive and must match exactly
  • The section index starts at 0

Publishing and Managing Forms

Create a form in One Request

curl -X POST https://app.penneo.com/collect/api/v1/forms \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d @your-form.json

This creates a form in DRAFT status.

Publish a Draft Form

curl -X POST https://app.penneo.com/collect/api/v1/forms/{externalId}/publish \
  -H "Authorization: Bearer YOUR_TOKEN"

Update an Existing Form

curl -X PUT https://app.penneo.com/collect/api/v1/forms/{externalId} \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d @updated-form.json

Note: Updating an ACTIVE form creates a new DRAFT version. Add ?publish=true to publish immediately.

Archive a Form

curl -X POST https://app.penneo.com/collect/api/v1/forms/{externalId}/archive \
  -H "Authorization: Bearer YOUR_TOKEN"

Retrieving Submission Data

Get All Submissions for a Form

curl -X GET "https://app.penneo.com/collect/api/v1/forms/{externalId}/answers?limit=100&offset=0" \
  -H "Authorization: Bearer YOUR_TOKEN"

Query Parameters:

  • limit: Number of submissions to return (1-500, default: 500)
  • offset: Number of submissions to skip (default: 0)

Get Submission by Casefile ID

curl -X GET https://app.penneo.com/collect/api/v1/casefiles/{casefileId}/answers \
  -H "Authorization: Bearer YOUR_TOKEN"

Response Format

Submission data is returned as structured JSON, making it easy to integrate with your systems:

{
  "submissions": [
    {
      "casefileId": 12345,
      "submittedAt": "2025-11-24T10:30:00Z",
      "answers": {
        "text_FullName_0": "John Doe",
        "email_EmailAddress_0": "[email protected]",
        "phone_PhoneNumber_0": "+4512345678",
        "date_DateOfBirth_1": "1990-05-15",
        "choice_Department_1": "engineering"
      },
      "primarySigner": {
        "fullName": "John Doe",
        "email": "[email protected]"
      },
      "additionalSigners": [
        {
          "fullName": "Jane Smith",
          "email": "[email protected]",
          "role": "Guarantor"
        }
      ],
      "status": "SIGNED"
    }
  ],
  "total": 42,
  "limit": 100,
  "offset": 0
}

Field Key Format

When the end user submits data, the HTML input fields default to the following format (if not specified when creating the form)

<type>_<CamelCaseLabel>_<SectionIndex>

Examples:

  • text_FullName_0 - Text field labeled "Full Name" in section 0
  • email_EmailAddress_0 - Email field in section 0
  • number_MonthlyIncome_2 - Number field in section 2
  • choice_Department_1 - Choice field in section 1

This is the same format used when fetch answers through the above example.

You are however allowed to set your own field names.

Tips and Best Practices

  1. Use Primary Signer Mapping: Set mapTo: "primarySigner.name" and mapTo: "primarySigner.email" to automatically identify form fillers, saving them time

  2. Provide Clear Instructions: Use HTML fields to give users context about what information is needed and why. Important: The HTML field only supports these tags: <p>, <em>, <strong>, <ul>, and <li>. No other HTML tags are allowed

  3. Validate Appropriately: Use validation rules to ensure data quality, but don't over-validate and frustrate users

  4. Organize with Sections: Group related fields into logical sections with descriptive titles

  5. Make Optional When Possible: Only require fields that are absolutely necessary

  6. Use Appropriate Field Types:

    • Use NIN for national IDs to get automatic validation
    • Use BUSINESS_ID for business registration numbers
    • Use EMAIL and PHONE for automatic format validation
    • Use CHOICE with different layouts (CHECKBOX, RADIO, SELECT) based on the number of options
  7. Configure Signers Thoughtfully:

    • Use predefinedSigners for known signers (like HR or management)
    • Use additionalSignersConfig with clear slot descriptions to guide users
    • Set realistic max values for additional signers
  8. Choose the Right Language: Set the language field to match your target audience. This determines the language of notification emails and the default language of the signing page (users can change it if needed)

  9. Handle Decimal Numbers: Set allowDecimals: true for monetary values and measurements


Success and Cancel URLs

You can configure custom redirect URLs for your forms to control where users are sent after completing or cancelling the signing process.

Available Options

PropertyDescription
successUrlURL where users are redirected after successfully completing the signing process
cancelUrlURL where users are redirected if they cancel or abandon the signing process

Example Usage

{
  "name": "Customer Onboarding",
  "language": "EN",
  "successUrl": "https://yourapp.com/onboarding/complete",
  "cancelUrl": "https://yourapp.com/onboarding/cancelled",
  "sections": [
    {
      "title": "Your Information",
      "fields": [
        {
          "type": "TEXT",
          "label": "Full Name",
          "required": true,
          "mapTo": "primarySigner.name"
        },
        {
          "type": "EMAIL",
          "label": "Email",
          "required": true,
          "mapTo": "primarySigner.email"
        }
      ]
    }
  ]
}

Chaining Forms Together

You can use successUrl to chain multiple forms together or integrate with external processes. By setting the successUrl of one form to point to another form's URL, users are automatically directed to the next step after completing the signing process.

Example: Multi-Document Workflow

Form 1: Employment Contract
  └── successUrl: "https://app.penneo.com/collect/forms/{form2-external-id}"
        │
        ▼
Form 2: NDA Agreement
  └── successUrl: "https://app.penneo.com/collect/forms/{form3-external-id}"
        │
        ▼
Form 3: Benefits Enrollment
  └── successUrl: "https://yourapp.com/onboarding/complete"

Implementation:

  1. Create all forms in the chain
  2. Set each form's successUrl to the next form's public URL
  3. Set the final form's successUrl to your completion page
{
  "name": "Employment Contract",
  "language": "EN",
  "successUrl": "https://app.penneo.com/collect/forms/abc123-form2-external-id",
  "cancelUrl": "https://yourapp.com/onboarding/cancelled",
  "sections": [...]
}

Use Cases for Form Chaining:

  • Separate documents: Each form generates its own signed PDF document, useful when you need distinct legal documents (e.g., employment contract, NDA, confidentiality agreement)
  • Different signers per document: Each form can have its own predefinedSigners, allowing different internal stakeholders to sign different documents (e.g., HR signs the contract, Legal signs the NDA, Finance signs the benefits form)
  • External process integration: Redirect users to a third-party system between forms, such as a payment gateway, identity verification service, or scheduling tool