# Form Configuration Reference

**Last Updated:** 2026-02-15

Complete reference for all HubSpot form configurations, field mappings, and requirements across all 9 API endpoints.

## Overview

This document provides a comprehensive mapping of:

- Form GUIDs and constants
- Required vs optional fields
- Field name mappings (code → HubSpot)
- Field value transformations
- Hidden vs visible fields
- Default values

## Form GUIDs Summary

| Endpoint                           | Form GUID                              | Constant                         | API Type                  | Authentication        |
| ---------------------------------- | -------------------------------------- | -------------------------------- | ------------------------- | --------------------- |
| `collect-lead.php`                 | `a91b263c-7ca2-418b-b35c-9664c30e968b` | `HUBSPOT_FORM_GUID_TOOLS`        | Forms API v3              | Public (no auth)      |
| `submit-template.php`              | `11e392f7-aece-4969-8c39-402ee6cb2330` | `HUBSPOT_FORM_GUID_TEMPLATE`     | Forms API v3              | Secure (Bearer token) |
| `addon-request.php`                | `c2022eda-c9b4-4010-a02d-d920852585b1` | `HUBSPOT_FORM_GUID_ADDON`        | Forms API v3              | Secure (Bearer token) |
| `export-workdays.php`              | `a91b263c-7ca2-418b-b35c-9664c30e968b` | `HUBSPOT_FORM_GUID_WORKDAYS`     | Forms API v3              | Public (no auth)      |
| `shiftops-hubspot.php`             | `41d07332-6697-4daa-b27e-dd60515f9c0f` | `HUBSPOT_FORM_GUID_SHIFTOPS`     | Forms API v3              | Public (no auth)      |
| `shiftops-nps.php`                 | `804459f7-c18d-4da6-8a0b-a81f44bb8275` | `HUBSPOT_FORM_GUID_SHIFTOPS_NPS` | Forms API v3              | Public (no auth)      |
| `lead-capture.php`                 | `9f9d4e35-d8d9-4283-93b6-1a789e0a1281` | `HUBSPOT_FORM_GUID_LEAD_CAPTURE` | Forms API v3 + CRM API v3 | Secure (Bearer token) |
| `webinar-registration.php`         | N/A                                    | N/A                              | CRM API v3                | Secure (Bearer token) |
| `payroll-webinar-registration.php` | N/A                                    | N/A                              | CRM API v3                | Secure (Bearer token) |

## Field Mapping Reference

### Standard Contact Fields

| Code Field  | HubSpot Property        | Type  | Required | Default | Notes                        |
| ----------- | ----------------------- | ----- | -------- | ------- | ---------------------------- |
| `email`     | `email`                 | Email | Yes      | -       | Primary identifier           |
| `name`      | `firstname`, `lastname` | Text  | Yes      | -       | Parsed into two fields       |
| `firstname` | `firstname`             | Text  | Yes      | -       | Direct mapping               |
| `lastname`  | `lastname`              | Text  | Yes      | -       | Direct mapping               |
| `phone`     | `phone`                 | Phone | Optional | -       | Normalized to E.164          |
| `company`   | `company`               | Text  | Optional | `""`    | Empty string if not provided |

### Demo Booking Form Fields

| Code Field          | Salesforce ID      | HubSpot Property        | Type     | Required | Notes                                    |
| ------------------- | ------------------ | ----------------------- | -------- | -------- | ---------------------------------------- |
| `rolle_im_betrieb`  | -                  | `rolle_im_betrieb__c`   | dropdown | No       | NEW: Rolle im Betrieb (5 options)        |
| `00N7Q00000JqXuC`   | `00N7Q00000JqXuC`  | `anzahl_mitarbeiter__c` | dropdown | No       | UPDATED: Anzahl Mitarbeitende (new ranges) |
| `00Naa000000Grzd`   | `00Naa000000Grzd`  | `industry__c`           | dropdown | No       | In welcher Branche (189 options)         |
| `woher_erfahren`    | -                  | `woher_erfahren`        | dropdown | No       | UPDATED: Wie hast du von uns erfahren (10 options, includes trade fair) |

**Removed Fields:**
- ~~`00N7Q00000JqXu7`~~ → ~~`anzahl_standorte__c`~~ (Anzahl Standorte - REMOVED 2026-03-13)

**See:** `docs/systems/forms/DEMO_FORM_FIELD_MAPPINGS.md` for complete field reference

### UTM Tracking Fields

| Code Field     | HubSpot Property  | Type     | Required | Default            | Notes                                            |
| -------------- | ----------------- | -------- | -------- | ------------------ | ------------------------------------------------ |
| `utm_source`   | `source__c`       | Text     | Optional | `""`               | Custom property                                  |
| `utm_medium`   | `utm_medium__c`   | Text     | Optional | `""`               | Custom property                                  |
| `utm_campaign` | `utm_campaign__c` | Text     | Optional | `""`               | Custom property                                  |
| `utm_term`     | `utm_term__c`     | Text     | Optional | `""`               | Custom property                                  |
| `utm_content`  | `content__c`      | Text     | Optional | `""`               | Custom property (note: different from `content`) |
| `gclid`        | `gclid__c`        | Text     | Optional | `""`               | Google Click ID                                  |
| `leadSource`   | `leadsource`      | Dropdown | Optional | `"Direct Traffic"` | Standard HubSpot field                           |
| `partner`      | `partner__c`      | Text     | Optional | `""`               | Custom property                                  |

### Signup Type Fields

| Code Field   | HubSpot Property  | Type | Required | Default       | Notes                            |
| ------------ | ----------------- | ---- | -------- | ------------- | -------------------------------- |
| `signuptype` | `sign_up_type__c` | Text | Optional | Form-specific | See form-specific defaults below |

### Content Fields

| Code Field         | HubSpot Property | Type | Required | Default       | Notes                            |
| ------------------ | ---------------- | ---- | -------- | ------------- | -------------------------------- |
| `content`          | `content`        | Text | Optional | Form-specific | See form-specific defaults below |
| `content_type`     | `content`        | Text | Optional | -             | Used by submit-template.php      |
| `tool_name`        | `content`        | Text | Optional | -             | Used by collect-lead.php         |
| `tool_description` | `content`        | Text | Optional | -             | Used by collect-lead.php         |

### Lead Status Fields

| Code Field | HubSpot Property | Type     | Required | Default            | Notes                  |
| ---------- | ---------------- | -------- | -------- | ------------------ | ---------------------- |
| N/A        | `hs_lead_status` | Dropdown | Optional | `"NEW"` | Standard HubSpot field; use `"NEW"` to match form options |

### Record Type Fields

| Code Field | HubSpot Property            | Type     | Required | Default                | Notes                |
| ---------- | --------------------------- | -------- | -------- | ---------------------- | -------------------- |
| N/A        | `record_type_id__dropdown_` | Dropdown | Optional | `"012aa0000013oZCAAY"` | Record Type: Inbound |

### Recycled Lead Fields

| Code Field | HubSpot Property        | Type    | Required | Default | Notes       |
| ---------- | ----------------------- | ------- | -------- | ------- | ----------- |
| N/A        | `recycled_inbound_lead` | Boolean | Optional | `false` | Default: No |

## Form-Specific Field Mappings

### 1. collect-lead.php (Tools Lead Collection)

**Form GUID:** `a91b263c-7ca2-418b-b35c-9664c30e968b`

**Required Fields:**

- `email` → `email`
- `name` → Parsed into `firstname`, `lastname`
- `sign_up_type__c` → `"Tools Page"` (static)
- `content` → `$toolDescription` or `$toolName` (dynamic)

**Optional Fields:**

- `tool_name` → `tool_type` (HubSpot property)
- `tool_data` → `calculation_data` (JSON string)
- `source` → `content` (if `tool_name` not provided)
- `description` → Formatted tool data string
- `company` → `""` (hidden, empty)

**Field Transformations:**

- `name` parsing: Split on first space → `firstname` (first part), `lastname` (remaining parts)
- `tool_data` → JSON encoded in `calculation_data`
- `tool_data` → Formatted string in `description`

**Default Values:**

- `sign_up_type__c`: `"Tools Page"`
- `hs_lead_status`: `"NEW"`
- `company`: `""`
- `record_type_id__dropdown_`: `"012aa0000013oZCAAY"`
- `recycled_inbound_lead`: `false`

### 2. submit-template.php (Template Downloads)

**Form GUID:** `11e392f7-aece-4969-8c39-402ee6cb2330`

**Required Fields:**

- `email` → `email`
- `firstname` → `firstname`
- `lastname` → `lastname`
- `content` → `$content_type` (with " - Template" suffix removed)

**Optional Fields:**

- `phone` → `phone` (only added if not empty)
- `industry` → `industry` (default: `"gastronomie"`)
- `company_size` → `company_size` (default: `"1"`)
- `template_type__c` → Detected from `content_type` (Schichtplan, Dienstplan, Zeiterfassung)
- `template_category__c` → `"Shift Planning"` or `"Duty Planning"` (based on template type)
- `source__c` → `$utm_source`
- `utm_campaign__c` → `$utm_campaign`

**Field Transformations:**

- `content_type` → Remove " - Template" suffix → `content`
- `content_type` → Extract template type → `template_type__c`
- Template type detection:
  - Contains "Schichtplan" → `template_type__c`: `"Schichtplan"`, `template_category__c`: `"Shift Planning"`
  - Contains "Dienstplan" → `template_type__c`: `"Dienstplan"`, `template_category__c`: `"Duty Planning"`
  - Contains "Zeiterfassung" → `template_type__c`: `"Zeiterfassung"`

**Default Values:**

- `sign_up_type__c`: `"Template Download"`
- `hs_lead_status`: `"NEW"`
- `industry`: `"gastronomie"`
- `company_size`: `"1"`
- `record_type_id__dropdown_`: `"012aa0000013oZCAAY"`
- `recycled_inbound_lead`: `false`

### 3. addon-request.php (Add-on Pricing Inquiries)

**Form GUID:** `c2022eda-c9b4-4010-a02d-d920852585b1`

**Required Fields:**

- `email` → `email`
- `name` → Parsed into `firstname`, `lastname`
- `message` → `description`
- `addon` → `content`
- `sign_up_type__c` → Normalized via `normalizeSignupType()`

**Optional Fields:**

- `company` → `company`
- `phone` → `phone`
- `pricing_inquiry_type` → `$addon` (custom field, if exists)

**Field Transformations:**

- `name` parsing: Split on first space → `firstname`, `lastname`
- `signuptype` normalization:
  - Enterprise options → `"Enterprise Pricing Inquiry"`
  - Add-on options → `"Add-on Pricing Inquiry"`
- `addon` → `content` (with fallback: `"Add-on Pricing Inquiry"`)

**Signup Type Normalization:**

- Enterprise: `"enterprise pricing inquiry"`, `"enterprise_inquiry"`, `"enterprise"`, `"enterprise add-on"`, `"enterprise addon"`, `"enterprise modal"` → `"Enterprise Pricing Inquiry"`
- Add-on: `"add-on pricing inquiry"`, `"add_on_pricing_inquiry"`, `"addon pricing inquiry"`, `"pricing_inquiry"`, `"pricing inquiry"`, `"add-on"`, `"addon"`, `"pricing"` → `"Add-on Pricing Inquiry"`
- Fallback: If `$addon === 'Enterprise'` → `"Enterprise Pricing Inquiry"`, otherwise → `"Add-on Pricing Inquiry"`

**Default Values:**

- `sign_up_type__c`: Normalized value (see above)
- `hs_lead_status`: `"NEW"`
- `content`: `$addon` or `"Add-on Pricing Inquiry"`
- `record_type_id__dropdown_`: `"012aa0000013oZCAAY"`
- `recycled_inbound_lead`: `false`

**Addon Values:**

- `"Ordio Events"`
- `"Hardware Terminals"`
- `"Personaldienstleister"`
- `"QR-Code Multi-Checkin"`
- `"Trinkgeld"`
- `"Enterprise"`

### 4. export-workdays.php (Workdays Calculator Export)

**Form GUID:** `a91b263c-7ca2-418b-b35c-9664c30e968b` (same as tools)

**Required Fields:**

- `email` → `email`
- `sign_up_type__c` → `"Tools Page"` (static)
- `content` → `"Arbeitstage-Rechner"` (static)

**Optional Fields:**

- `calculation_data` → `calculation_data` (JSON string)
- `marketingConsent` → Not sent to HubSpot (used for email consent only)

**Field Transformations:**

- `calculationData` → JSON encoded → `calculation_data`
- `exportData` → Not sent to HubSpot (used for file generation only)

**Default Values:**

- `sign_up_type__c`: `"Tools Page"`
- `content`: `"Arbeitstage-Rechner"`
- `record_type_id__dropdown_`: `"012aa0000013oZCAAY"`
- `recycled_inbound_lead`: `false`

### 5. shiftops-hubspot.php (ShiftOps Report Unlock)

**Form GUID:** `41d07332-6697-4daa-b27e-dd60515f9c0f`

**Required Fields:**

- `email` → `email`
- `firstname` → `firstname`
- `lastname` → `lastname`
- `sign_up_type__c` → `"Tools Page"` (static)
- `content` → `"ShiftOps"` (static)

**Optional Fields:**

- `phone` → `phone`
- `shiftops_business_name` → `company`
- `shiftops_index` → `shiftops_index` (hidden)
- `shiftops_grade` → `grade` (hidden)
- `shiftops_place_id` → Not sent to HubSpot (used for report generation)
- `description` → Formatted ShiftOps report data
- `calculation_data` → JSON encoded ShiftOps data
- `tool_type` → `"shiftops"`

**Field Transformations:**

- `shiftops_business_name` → `company`
- Report data → Formatted string → `description`
- Report data → JSON encoded → `calculation_data`

**Default Values:**

- `sign_up_type__c`: `"Tools Page"`
- `content`: `"ShiftOps"`
- `tool_type`: `"shiftops"`
- `record_type_id__dropdown_`: `"012aa0000013oZCAAY"`
- `recycled_inbound_lead`: `false`

**Rate Limiting:**

- Max submissions: 3 per hour per IP/email combination
- Window: 60 minutes
- Response: 429 Too Many Requests if exceeded

### 6. shiftops-nps.php (ShiftOps NPS Survey)

**Form GUID:** `804459f7-c18d-4da6-8a0b-a81f44bb8275`

**Required Fields:**

- `email` → `email`
- `nps_score` → `nps_score` (0-10)
- `sign_up_type__c` → `"Tools Page"` (static)
- `content` → `"ShiftOps NPS"` (static)

**Optional Fields:**

- `nps_feedback` → `nps_feedback`
- `nps_category` → Calculated: `"Promoter"` (9-10), `"Passive"` (7-8), `"Detractor"` (0-6)
- `shiftops_business_name` → `company`
- `shiftops_index` → `shiftops_index` (hidden)
- `shiftops_grade` → `grade` (hidden)
- `shiftops_place_id` → Not sent to HubSpot
- `shiftops_nps_context` → Consolidated context string
- `nps_survey_version` → `"beta-v1"` (default)

**Field Transformations:**

- `nps_score` → `nps_score` (0-10)
- `nps_score` → Calculate category → `nps_category`
- Context data → Consolidated string → `shiftops_nps_context`

**NPS Category Calculation:**

- 9-10 → `"Promoter"`
- 7-8 → `"Passive"`
- 0-6 → `"Detractor"`

**Default Values:**

- `sign_up_type__c`: `"Tools Page"`
- `content`: `"ShiftOps NPS"`
- `nps_survey_version`: `"beta-v1"`
- `record_type_id__dropdown_`: `"012aa0000013oZCAAY"`
- `recycled_inbound_lead`: `false`

### 7. lead-capture.php (Lead Capture Popup)

**Form GUID:** `9f9d4e35-d8d9-4283-93b6-1a789e0a1281`

**Step 1 Required Fields:**

- `name` → Parsed into `firstname`, `lastname`
- `phone` → `phone` (normalized to E.164)
- `email` → `email` (temporary email if not provided: `lead-{leadId}@temp.ordio.com`)

**Step 1 Optional Fields:**

- `sourcePage` → `content` (dynamic)
- `leadSource` → `leadsource`
- `triggerType` → `lead_capture_trigger`

**Step 2 Optional Fields:**

- `email` → `email` (replaces temporary email)
- `notes` → `additional_information__c`
- `callPreference` → Not sent to HubSpot (stored in Google Sheets only)

**Field Transformations:**

- `name` parsing: Split on first space → `firstname`, `lastname`
- `phone` normalization: E.164 format
- Temporary email generation: `lead-{leadId}@temp.ordio.com`
- `sourcePage` → `content` (or `"Lead Capture"` if empty)

**Default Values:**

- `sign_up_type__c`: `"Lead Capture Form"`
- `content`: `$sourcePage` or `"Lead Capture"`
- `company`: `""`
- `record_type_id__dropdown_`: `"012aa0000013oZCAAY"`
- `recycled_inbound_lead`: `false`

**Special Features:**

- Two-step process: Step 1 creates contact with temp email, Step 2 updates with real email
- Activity tracking: Tracks page view BEFORE contact creation via Events API
- Contact identification: Identifies existing contacts by `hubspotutk` before creation
- Duplicate detection: Checks for duplicates by phone/email

### 8. webinar-registration.php (Product Webinars)

**API Type:** CRM API v3 (no Forms API)

**Required Fields:**

- `full_name` → Parsed into `firstname`, `lastname`
- `email` → `email`
- `webinar_date` → Custom property (if configured)

**Optional Fields:**

- `phone` → `phone`

**Field Transformations:**

- `full_name` parsing: Split on first space → `firstname`, `lastname`
- `webinar_date` → Custom property (if exists in HubSpot)

**Default Values:**

- `sign_up_type__c`: `"Webinar Registration"`
- `content`: `"Produkt"`

**Special Features:**

- Google Sheets integration: Appends to Google Sheets spreadsheet
- CRM API v3: Uses direct contact creation (no Forms API)
- Page view tracking: Tracks page view before contact creation

### 9. payroll-webinar-registration.php (Payroll Webinars)

**API Type:** CRM API v3 (no Forms API)

**Required Fields:**

- `full_name` → Parsed into `firstname`, `lastname`
- `email` → `email`
- `webinar_date` → Custom property (if configured)

**Optional Fields:**

- `phone` → `phone`

**Field Transformations:**

- `full_name` parsing: Split on first space → `firstname`, `lastname`
- `webinar_date` → Custom property (if exists in HubSpot)

**Default Values:**

- `sign_up_type__c`: `"Webinar Registration"`
- `content`: `"Payroll"`

**Special Features:**

- Google Sheets integration: Appends to Payroll Webinar spreadsheet
- CRM API v3: Uses direct contact creation (no Forms API)
- Page view tracking: Tracks page view before contact creation

## Context Fields (Forms API v3)

All Forms API v3 endpoints use these context fields:

| Context Field | Source                                            | Required | Notes                                    |
| ------------- | ------------------------------------------------- | -------- | ---------------------------------------- |
| `hutk`        | `$_COOKIE['hubspotutk']` or request body          | Critical | Links form submission to browser session |
| `ipAddress`   | `$_SERVER['REMOTE_ADDR']`                         | Optional | For geolocation                          |
| `pageUri`     | `getActualPageUrl($page_url, $referrer)`          | Optional | Conversion page URL                      |
| `pageName`    | `getPageNameFromUrl($page_url, $defaultPageName)` | Optional | Human-readable page name                 |

**Priority Order for `pageUri`:**

1. `$page_url` from input (if valid URL)
2. `$referrer` from input (if valid URL)
3. `$_SERVER['HTTP_REFERER']` (if valid URL and not API file)
4. `null` (never use API file URL)

## Related Documentation

- [Form-to-Page Mapping](FORM_TO_PAGE_MAPPING.md) - Which forms are used where
- [HubSpot API Reference](../apis/HUBSPOT_API_REFERENCE.md) - Complete API documentation
- [HubSpot Form Field Configuration](../../guides/HUBSPOT_FORM_FIELD_CONFIGURATION.md) - HubSpot form configuration guide
