# HubSpot API Reference

**Last Updated:** 2026-01-10

Complete reference documentation for all HubSpot API endpoints used across the Ordio website.

## Overview

This document provides comprehensive documentation for all 9 HubSpot API endpoints, including request/response schemas, error handling patterns, and integration examples.

## API Endpoints Summary

| Endpoint                           | Form GUID                              | Constant                         | Purpose                         | API Type                  |
| ---------------------------------- | -------------------------------------- | -------------------------------- | ------------------------------- | ------------------------- |
| `collect-lead.php`                 | `a91b263c-7ca2-418b-b35c-9664c30e968b` | `HUBSPOT_FORM_GUID_TOOLS`        | Universal tools lead collection | Forms API v3              |
| `submit-template.php`              | `11e392f7-aece-4969-8c39-402ee6cb2330` | `HUBSPOT_FORM_GUID_TEMPLATE`     | Template downloads              | Forms API v3              |
| `addon-request.php`                | `c2022eda-c9b4-4010-a02d-d920852585b1` | `HUBSPOT_FORM_GUID_ADDON`        | Add-on pricing inquiries        | Forms API v3              |
| `export-workdays.php`              | `a91b263c-7ca2-418b-b35c-9664c30e968b` | `HUBSPOT_FORM_GUID_WORKDAYS`     | Workdays calculator export      | Forms API v3              |
| `shiftops-hubspot.php`             | `41d07332-6697-4daa-b27e-dd60515f9c0f` | `HUBSPOT_FORM_GUID_SHIFTOPS`     | ShiftOps report generation      | Forms API v3 (Public)     |
| `shiftops-nps.php`                 | `804459f7-c18d-4da6-8a0b-a81f44bb8275` | `HUBSPOT_FORM_GUID_SHIFTOPS_NPS` | ShiftOps NPS surveys            | Forms API v3 (Public)     |
| `lead-capture.php`                 | `9f9d4e35-d8d9-4283-93b6-1a789e0a1281` | `HUBSPOT_FORM_GUID_LEAD_CAPTURE` | Lead capture popup              | Forms API v3 + CRM API v3 |
| `webinar-registration.php`         | N/A                                    | N/A                              | Product webinars                | CRM API v3                |
| `payroll-webinar-registration.php` | N/A                                    | N/A                              | Payroll webinars                | CRM API v3                |

## Common Patterns

### Request Headers

All endpoints accept:

```
Content-Type: application/json
```

### Response Format

**Success Response:**

```json
{
  "success": true,
  "message": "Success message",
  "data": {
    // Endpoint-specific data
  }
}
```

**Error Response:**

```json
{
  "success": false,
  "error": "Error message",
  "errors": [
    {
      "field": "field_name",
      "message": "Validation error message"
    }
  ]
}
```

### UTM Parameter Handling

All endpoints accept UTM parameters:

- `utm_source`
- `utm_medium`
- `utm_campaign`
- `utm_term`
- `utm_content`
- `gclid`
- `leadSource`
- `partner`
- `signuptype`
- `page_url`
- `referrer`
- `hubspotutk` (CRITICAL for Forms API v3)

**Priority Order:**

1. Request body parameters
2. Cookie values
3. URL parameters (from `page_url`)

### Error Handling

All endpoints use standardized error handling:

- **400 Bad Request:** Validation errors
- **405 Method Not Allowed:** Wrong HTTP method
- **429 Too Many Requests:** Rate limit exceeded
- **500 Internal Server Error:** Server errors

### Retry Logic

All endpoints use `makeHubSpotAPICall()` helper with:

- **Max Retries:** 3 (configurable)
- **Initial Retry Delay:** 1 second
- **Exponential Backoff:** Yes
- **Retryable Errors:** Network errors, 429, 5xx

## Endpoint Documentation

### 1. collect-lead.php

**Endpoint:** `/v2/api/collect-lead.php`  
**Method:** POST  
**Form GUID:** `a91b263c-7ca2-418b-b35c-9664c30e968b`  
**Constant:** `HUBSPOT_FORM_GUID_TOOLS`  
**API Type:** Forms API v3

**Purpose:** Universal tools lead collection for calculator/tool pages.

**Request Schema:**

```json
{
  "email": "string (required, email format)",
  "name": "string (required, max 100 chars)",
  "tool_name": "string (optional, max 100 chars)",
  "tool_description": "string (optional, max 200 chars)",
  "tool_data": {
    // Tool-specific calculation data (optional, object)
  },
  "source": "string (optional, e.g., 'Minijob-Rechner Export')",
  "utm_source": "string (optional)",
  "utm_medium": "string (optional)",
  "utm_campaign": "string (optional)",
  "utm_term": "string (optional)",
  "utm_content": "string (optional)",
  "gclid": "string (optional)",
  "leadSource": "string (optional)",
  "partner": "string (optional)",
  "signuptype": "string (optional, default: 'tools_page')",
  "page_url": "string (optional, URL)",
  "referrer": "string (optional, URL)",
  "hubspotutk": "string (optional, CRITICAL for Forms API v3)"
}
```

**Response Schema:**

```json
{
  "success": true,
  "message": "Lead collected successfully",
  "data": {
    "contactId": "string",
    "vid": "number"
  }
}
```

**Field Mappings:**

- `name` → Parsed into `firstname` and `lastname`
- `tool_name` → `tool_type` (HubSpot property)
- `tool_data` → `calculation_data` (HubSpot property, JSON string)
- `signuptype` → `sign_up_type__c` (default: "Tools Page")
- `source` → `content` (HubSpot property)

**Used By:**

- `tools_arbeitstage_rechner.php`
- `tools_industrieminuten_rechner.php`
- `tools_mehrwertsteuer_rechner.php`
- `tools_midijob_rechner.php`
- `tools_stundenlohnrechner.php`
- `tools_tvoed_sue.php`
- `tools_urlaubsanspruchrechner.php`
- `tools_zinseszinsrechner.php`
- `tools_zuschlagsrechner.php`

**Example Request:**

```javascript
fetch("/v2/api/collect-lead.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    name: "Max Mustermann",
    tool_name: "Minijob-Rechner",
    tool_description: "Minijob Netto-Gehalt Berechnung",
    tool_data: {
      brutto: 520,
      netto: 450,
      // ... calculation results
    },
    source: "Minijob-Rechner Export",
    hubspotutk: getCookie("hubspotutk"),
  }),
});
```

### 2. submit-template.php

**Endpoint:** `/v2/api/submit-template.php`  
**Method:** POST  
**Form GUID:** `11e392f7-aece-4969-8c39-402ee6cb2330`  
**Constant:** `HUBSPOT_FORM_GUID_TEMPLATE`  
**API Type:** Forms API v3

**Purpose:** Template download form submissions.

**Request Schema:**

```json
{
  "email": "string (required, email format)",
  "firstname": "string (required, min 1, max 100 chars)",
  "lastname": "string (required, min 1, max 100 chars)",
  "phone": "string (optional, phone format, max 50 chars)",
  "industry": "string (optional, max 100 chars, default: 'gastronomie')",
  "company_size": "string (optional, max 50 chars, default: '1')",
  "content_type": "string (optional, e.g., 'Schichtplan Vorlage - Template')",
  "utm_source": "string (optional)",
  "utm_medium": "string (optional)",
  "utm_campaign": "string (optional)",
  "utm_term": "string (optional)",
  "utm_content": "string (optional)",
  "gclid": "string (optional)",
  "leadSource": "string (optional)",
  "partner": "string (optional)",
  "signuptype": "string (optional, default: 'template_download')",
  "page_url": "string (optional, URL)",
  "referrer": "string (optional, URL)",
  "hubspotutk": "string (optional, CRITICAL for Forms API v3)"
}
```

**Response Schema:**

```json
{
  "success": true,
  "message": "Template download submitted successfully",
  "data": {
    "contactId": "string",
    "vid": "number"
  }
}
```

**Field Mappings:**

- `content_type` → `content` (HubSpot property)
- `signuptype` → `sign_up_type__c` (default: "Template Download")

**Used By:**

- `templates_dienstplan.php`
- `templates_schichtplan.php`
- `templates_template.php`

**Example Request:**

```javascript
fetch("/v2/api/submit-template.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    firstname: "Max",
    lastname: "Mustermann",
    phone: "+49 123 456789",
    industry: "gastronomie",
    company_size: "1",
    content_type: "Schichtplan Vorlage - Template",
    hubspotutk: getCookie("hubspotutk"),
  }),
});
```

### 3. addon-request.php

**Endpoint:** `/v2/api/addon-request.php`  
**Method:** POST  
**Form GUID:** `c2022eda-c9b4-4010-a02d-d920852585b1`  
**Constant:** `HUBSPOT_FORM_GUID_ADDON`  
**API Type:** Forms API v3

**Purpose:** Add-on pricing inquiry form submissions.

**Request Schema:**

```json
{
  "name": "string (required, min 1, max 200 chars)",
  "email": "string (required, email format)",
  "company": "string (optional, max 200 chars, required for Enterprise)",
  "phone": "string (optional, phone format, max 50 chars)",
  "message": "string (required, min 1, max 5000 chars)",
  "addon": "string (required, max 100 chars)",
  "utm_source": "string (optional)",
  "utm_medium": "string (optional)",
  "utm_campaign": "string (optional)",
  "utm_term": "string (optional)",
  "utm_content": "string (optional)",
  "gclid": "string (optional)",
  "leadSource": "string (optional)",
  "partner": "string (optional)",
  "signuptype": "string (optional, normalized: 'Add-on Pricing Inquiry' or 'Enterprise Pricing Inquiry')",
  "page_url": "string (optional, URL)",
  "referrer": "string (optional, URL)",
  "hubspotutk": "string (optional, CRITICAL for Forms API v3)"
}
```

**Response Schema:**

```json
{
  "success": true,
  "message": "Pricing inquiry submitted successfully",
  "data": {
    "contactId": "string",
    "vid": "number"
  }
}
```

**Field Mappings:**

- `name` → Parsed into `firstname` and `lastname`
- `addon` → `content` (HubSpot property)
- `signuptype` → Normalized via `normalizeSignupType()`:
  - Enterprise options → "Enterprise Pricing Inquiry"
  - Add-on options → "Add-on Pricing Inquiry"

**Used By:**

- `v2/base/sections/pricing-addons.php` (5 addons)
- `v2/base/sections/enterprise-box.php` (Enterprise)

**Addon Values:**

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

**Example Request:**

```javascript
fetch("/v2/api/addon-request.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Max Mustermann",
    email: "user@example.com",
    company: "Example GmbH",
    phone: "+49 123 456789",
    message: "Interested in pricing",
    addon: "Ordio Events",
    signuptype: "add-on pricing inquiry",
    hubspotutk: getCookie("hubspotutk"),
  }),
});
```

### 4. export-workdays.php

**Endpoint:** `/v2/api/export-workdays.php`  
**Method:** POST  
**Form GUID:** `a91b263c-7ca2-418b-b35c-9664c30e968b` (same as tools)  
**Constant:** `HUBSPOT_FORM_GUID_WORKDAYS`  
**API Type:** Forms API v3

**Purpose:** Workdays calculator export with email collection.

**Request Schema:**

```json
{
  "email": "string (required, email format)",
  "format": "string (required, enum: ['xlsx', 'csv', 'pdf'])",
  "calculationData": "string (required, JSON string, max 50000 chars)",
  "exportData": "string (required, JSON string, max 100000 chars)",
  "marketingConsent": "string (optional, boolean)",
  "utm_source": "string (optional)",
  "utm_medium": "string (optional)",
  "utm_campaign": "string (optional)",
  "utm_term": "string (optional)",
  "utm_content": "string (optional)",
  "gclid": "string (optional)",
  "leadSource": "string (optional)",
  "page_url": "string (optional, URL)",
  "referrer": "string (optional, URL)",
  "hubspotutk": "string (optional, CRITICAL for Forms API v3)"
}
```

**Response Schema:**

```json
{
  "success": true,
  "filename": "arbeitstage-berechnung_2026-01-10_12-00-00.xlsx",
  "content": "base64-encoded-file-content",
  "message": "Export generated successfully"
}
```

**Field Mappings:**

- `calculationData` → `calculation_data` (HubSpot property, JSON string)
- `sign_up_type__c` → "Tools Page"
- `content` → "Arbeitstage-Rechner"

**Used By:**

- `tools_arbeitstage_rechner.php`

**Example Request:**

```javascript
fetch("/v2/api/export-workdays.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    format: "xlsx",
    calculationData: JSON.stringify(calculationData),
    exportData: JSON.stringify(exportData),
    marketingConsent: "true",
    hubspotutk: getCookie("hubspotutk"),
  }),
});
```

### 5. shiftops-hubspot.php

**Endpoint:** `/v2/api/shiftops-hubspot.php`  
**Method:** POST  
**Form GUID:** `41d07332-6697-4daa-b27e-dd60515f9c0f`  
**Constant:** `HUBSPOT_FORM_GUID_SHIFTOPS`  
**API Type:** Forms API v3 (Public Endpoint)

**Purpose:** ShiftOps report unlock form submission.

**Request Schema:**

```json
{
  "firstname": "string (required, max 100 chars)",
  "lastname": "string (required, max 100 chars)",
  "email": "string (required, email format)",
  "phone": "string (optional, phone format, max 50 chars)",
  "shiftops_business_name": "string (optional, max 200 chars)",
  "shiftops_index": "number (optional)",
  "shiftops_grade": "string (optional, max 10 chars)",
  "shiftops_place_id": "string (optional, max 100 chars)",
  "utm_source": "string (optional)",
  "utm_medium": "string (optional)",
  "utm_campaign": "string (optional)",
  "utm_term": "string (optional)",
  "utm_content": "string (optional)",
  "gclid": "string (optional)",
  "leadSource": "string (optional)",
  "page_url": "string (optional, URL)",
  "referrer": "string (optional, URL)",
  "hubspotutk": "string (optional, CRITICAL for Forms API v3)"
}
```

**Response Schema:**

```json
{
  "success": true,
  "message": "Report unlocked successfully",
  "data": {
    "contactId": "string",
    "vid": "number"
  }
}
```

**Field Mappings:**

- `shiftops_business_name` → `company` (HubSpot property)
- `shiftops_index` → `shiftops_index` (HubSpot property, hidden)
- `shiftops_grade` → `grade` (HubSpot property, hidden)
- `sign_up_type__c` → "Tools Page"
- `content` → "ShiftOps"

**Used By:**

- `shiftops-report.php`

**Rate Limiting:**

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

**Example Request:**

```javascript
fetch("/v2/api/shiftops-hubspot.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    firstname: "Max",
    lastname: "Mustermann",
    email: "user@example.com",
    phone: "+49 123 456789",
    shiftops_business_name: "Example GmbH",
    shiftops_index: 75,
    shiftops_grade: "B",
    hubspotutk: getCookie("hubspotutk"),
  }),
});
```

### 6. shiftops-nps.php

**Endpoint:** `/v2/api/shiftops-nps.php`  
**Method:** POST  
**Form GUID:** `804459f7-c18d-4da6-8a0b-a81f44bb8275`  
**Constant:** `HUBSPOT_FORM_GUID_SHIFTOPS_NPS`  
**API Type:** Forms API v3 (Public Endpoint)

**Purpose:** ShiftOps NPS survey submission.

**Request Schema:**

```json
{
  "email": "string (required, email format)",
  "nps_score": "number (required, 0-10)",
  "nps_feedback": "string (optional, max 5000 chars)",
  "shiftops_business_name": "string (optional, max 200 chars)",
  "shiftops_index": "number (optional)",
  "shiftops_grade": "string (optional, max 10 chars)",
  "shiftops_place_id": "string (optional, max 100 chars)",
  "nps_survey_version": "string (optional, max 50 chars, default: 'beta-v1')",
  "page_url": "string (optional, URL)",
  "hubspotutk": "string (optional, CRITICAL for Forms API v3)"
}
```

**Response Schema:**

```json
{
  "success": true,
  "message": "NPS survey submitted successfully",
  "data": {
    "contactId": "string",
    "vid": "number"
  }
}
```

**Field Mappings:**

- `nps_score` → `nps_score` (HubSpot property)
- `nps_feedback` → `nps_feedback` (HubSpot property)
- `nps_category` → Calculated: "Promoter" (9-10), "Passive" (7-8), "Detractor" (0-6)
- `shiftops_nps_context` → Consolidated context string
- `sign_up_type__c` → "Tools Page"
- `content` → "ShiftOps NPS"

**Used By:**

- `shiftops-report.php`

**Example Request:**

```javascript
fetch("/v2/api/shiftops-nps.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    nps_score: 9,
    nps_feedback: "Great tool!",
    shiftops_business_name: "Example GmbH",
    shiftops_index: 75,
    shiftops_grade: "B",
    hubspotutk: getCookie("hubspotutk"),
  }),
});
```

### 7. lead-capture.php

**Endpoint:** `/v2/api/lead-capture.php`  
**Method:** POST  
**Form GUID:** `9f9d4e35-d8d9-4283-93b6-1a789e0a1281`  
**Constant:** `HUBSPOT_FORM_GUID_LEAD_CAPTURE`  
**API Type:** Forms API v3 + CRM API v3 (Fallback)

**Purpose:** Two-step progressive lead capture popup form submission.

**Request Schema (Step 1):**

```json
{
  "name": "string (required, max 200 chars)",
  "phone": "string (required, phone format, max 50 chars)",
  "sourcePage": "string (optional, auto-detected)",
  "leadSource": "string (optional, auto-detected)",
  "triggerType": "string (optional, auto-detected)",
  "utm_source": "string (optional)",
  "utm_medium": "string (optional)",
  "utm_campaign": "string (optional)",
  "utm_term": "string (optional)",
  "utm_content": "string (optional)",
  "gclid": "string (optional)",
  "hubspotutk": "string (optional, CRITICAL for Forms API v3)"
}
```

**Request Schema (Step 2):**

```json
{
  "email": "string (optional, email format)",
  "notes": "string (optional, max 5000 chars)",
  "callPreference": "string (optional)",
  "leadId": "string (required, from Step 1 response)"
}
```

**Response Schema (Step 1):**

```json
{
  "success": true,
  "message": "Lead captured successfully",
  "data": {
    "leadId": "LC-20260110120000-abc123",
    "contactId": "string",
    "vid": "number"
  }
}
```

**Response Schema (Step 2):**

```json
{
  "success": true,
  "message": "Additional information saved successfully",
  "data": {
    "contactId": "string",
    "vid": "number"
  }
}
```

**Field Mappings:**

- `name` → Parsed into `firstname` and `lastname`
- `sourcePage` → `lead_capture_trigger` (HubSpot property)
- `notes` → `additional_information__c` (HubSpot property)
- `sign_up_type__c` → "Lead Capture Form"
- `content` → `sourcePage` or "Lead Capture"

**Used By:**

- 105+ pages (all comparison, product, industry, template, download, webinar pages)

**Special Features:**

- **Two-Step Process:** Step 1 creates contact with temporary 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

**Example Request (Step 1):**

```javascript
fetch("/v2/api/lead-capture.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Max Mustermann",
    phone: "+49 123 456789",
    sourcePage: "compare_planday",
    triggerType: "time",
    hubspotutk: getCookie("hubspotutk"),
  }),
});
```

**Example Request (Step 2):**

```javascript
fetch("/v2/api/lead-capture.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    notes: "Interested in Schichtplanung",
    callPreference: "Morgen",
    leadId: "LC-20260110120000-abc123",
  }),
});
```

### 8. webinar-registration.php

**Endpoint:** `/v2/api/webinar-registration.php`  
**Method:** POST  
**Form GUID:** N/A  
**API Type:** CRM API v3

**Purpose:** Product webinar registration (no dedicated HubSpot form).

**Request Schema:**

```json
{
  "full_name": "string (required, min 1, max 200 chars)",
  "email": "string (required, email format)",
  "phone": "string (optional, phone format, max 50 chars)",
  "webinar_date": "string (required, YYYY-MM-DD format, weekday only)",
  "utm_source": "string (optional)",
  "utm_medium": "string (optional)",
  "utm_campaign": "string (optional)",
  "utm_term": "string (optional)",
  "utm_content": "string (optional)",
  "gclid": "string (optional)",
  "leadSource": "string (optional)",
  "page_url": "string (optional, URL)",
  "referrer": "string (optional, URL)",
  "hubspotutk": "string (optional)"
}
```

**Response Schema:**

```json
{
  "success": true,
  "message": "Webinar registration successful",
  "data": {
    "contactId": "string",
    "sheetsUpdated": true
  }
}
```

**Field Mappings:**

- `full_name` → Parsed into `firstname` and `lastname`
- `webinar_date` → Custom property (if configured)
- `sign_up_type__c` → "Webinar Registration"
- `content` → "Produkt"

**Used By:**

- `product_webinar.php`
- `webinar_trinkgeld.php`

**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

**Example Request:**

```javascript
fetch("/v2/api/webinar-registration.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    full_name: "Max Mustermann",
    email: "user@example.com",
    phone: "+49 123 456789",
    webinar_date: "2026-01-15",
    hubspotutk: getCookie("hubspotutk"),
  }),
});
```

### 9. payroll-webinar-registration.php

**Endpoint:** `/v2/api/payroll-webinar-registration.php`  
**Method:** POST  
**Form GUID:** N/A  
**API Type:** CRM API v3

**Purpose:** Payroll webinar registration (no dedicated HubSpot form).

**Request Schema:**

```json
{
  "full_name": "string (required, min 1, max 200 chars)",
  "email": "string (required, email format)",
  "phone": "string (optional, phone format, max 50 chars)",
  "webinar_date": "string (required, YYYY-MM-DD format, weekday only)",
  "utm_source": "string (optional)",
  "utm_medium": "string (optional)",
  "utm_campaign": "string (optional)",
  "utm_term": "string (optional)",
  "utm_content": "string (optional)",
  "gclid": "string (optional)",
  "leadSource": "string (optional)",
  "page_url": "string (optional, URL)",
  "referrer": "string (optional, URL)",
  "hubspotutk": "string (optional)"
}
```

**Response Schema:**

```json
{
  "success": true,
  "message": "Payroll webinar registration successful",
  "data": {
    "contactId": "string",
    "sheetsUpdated": true
  }
}
```

**Field Mappings:**

- `full_name` → Parsed into `firstname` and `lastname`
- `webinar_date` → Custom property (if configured)
- `sign_up_type__c` → "Webinar Registration"
- `content` → "Payroll"

**Used By:**

- `product_payroll_webinar.php`

**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

**Example Request:**

```javascript
fetch("/v2/api/payroll-webinar-registration.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    full_name: "Max Mustermann",
    email: "user@example.com",
    phone: "+49 123 456789",
    webinar_date: "2026-01-15",
    hubspotutk: getCookie("hubspotutk"),
  }),
});
```

## HubSpot API Helper Functions

### `makeHubSpotAPICall(url, method, headers, body, options)`

Standardized HubSpot API call with retry logic and error handling.

**Parameters:**

- `url` (string): HubSpot API URL
- `method` (string): HTTP method (default: 'POST')
- `headers` (array): HTTP headers
- `body` (string): Request body (JSON string)
- `options` (array): Options:
  - `maxRetries` (int): Max retries (default: 3)
  - `initialRetryDelay` (int): Initial retry delay in seconds (default: 1)
  - `timeout` (int): Request timeout in seconds (default: 30)
  - `connectTimeout` (int): Connection timeout in seconds (default: 10)
  - `userAgent` (string): User agent string
  - `logPrefix` (string): Log prefix for debugging

**Returns:** `array` - `['success' => bool, 'data' => mixed, 'httpCode' => int, 'error' => string]`

### `buildHubSpotFormsAPISecureUrl(formGuid)`

Build secure Forms API v3 URL (requires authentication).

**Parameters:**

- `formGuid` (string): HubSpot form GUID

**Returns:** `string` - Forms API v3 URL

### `buildHubSpotFormsAPIPublicUrl(formGuid)`

Build public Forms API v3 URL (no authentication required).

**Parameters:**

- `formGuid` (string): HubSpot form GUID

**Returns:** `string` - Public Forms API v3 URL

## Error Handling Patterns

### Validation Errors (400)

```json
{
  "success": false,
  "error": "Validation failed",
  "errors": [
    {
      "field": "email",
      "message": "Invalid email format"
    }
  ]
}
```

### Rate Limit Errors (429)

```json
{
  "success": false,
  "error": "Rate limit exceeded",
  "message": "Zu viele Anfragen. Bitte versuche es später erneut."
}
```

### Server Errors (500)

```json
{
  "success": false,
  "error": "Internal server error",
  "message": "Ein Fehler ist aufgetreten. Bitte versuche es später erneut."
}
```

## Common Integration Patterns

### Pattern 1: Forms API v3 (Recommended)

```php
$hubspotUrl = buildHubSpotFormsAPISecureUrl(HUBSPOT_FORM_GUID_TOOLS);
$hubspotData = [
    "submittedAt" => round(microtime(true) * 1000),
    "fields" => [
        ["name" => "email", "value" => $email],
        ["name" => "firstname", "value" => $firstname],
        // ... more fields
    ],
    "context" => [
        "hutk" => $hubspotutk,  // CRITICAL for activity tracking
        "pageUri" => $pageUrl,
        "pageName" => "Page Name"
    ]
];

$result = makeHubSpotAPICall($hubspotUrl, 'POST', [
    'Content-Type: application/json'
], json_encode($hubspotData));
```

### Pattern 2: CRM API v3 (Fallback)

```php
$hubspotUrl = 'https://api.hubapi.com/crm/v3/objects/contacts';
$contactData = [
    "properties" => [
        "email" => $email,
        "firstname" => $firstname,
        "lastname" => $lastname,
        // ... more properties
    ]
];

$result = makeHubSpotAPICall($hubspotUrl, 'POST', [
    'Authorization: Bearer ' . HUBSPOT_API_TOKEN,
    'Content-Type: application/json'
], json_encode($contactData));
```

## Related Documentation

- [Form-to-Page Mapping](../forms/FORM_TO_PAGE_MAPPING.md) - Which endpoints are used where
- [Form Configuration Reference](../forms/FORM_CONFIGURATION_REFERENCE.md) - Form field mappings
- [HubSpot Integration Guide](../../guides/HUBSPOT_INTEGRATION_GUIDE.md) - Complete integration guide
- [Shared Components](../shared-components/README.md) - Component usage
