Klyp Gravity Form to Hubspot
This plugin allows you to map Gravity Forms fields to Hubspot form fields.
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/klyp/klyp-gf-to-hubspot/archive/refs/heads/develop.zipReadme
Klyp Gravity Form to Hubspot
Map Gravity Forms fields to Hubspot form fields and deliver every submission to Hubspot.
Licensed under GPL-2.0-or-later. See License & Compliance.
Table of Contents
- Overview
- Prerequisites
- Installation
- Usage
- Project Structure
- Development Setup
- Testing
- Release Process
- Contributing
- Security
- License & Compliance
- Support & Contact
- Changelog
- Acknowledgments
Overview
A WordPress plugin that connects a Gravity Form to a Hubspot form. Each Gravity Forms field is mapped to a Hubspot property in the form editor; on submission the plugin builds a Hubspot payload from the entry and posts it to the Hubspot Forms submission endpoint.
Key features
- Per-field mapping in the form editor. Every supported field gets a Hubspot field to map setting under its Advanced tab, populated live from the Hubspot form.
- Nothing fails quietly. If Hubspot rejects a submission, the form does not submit — the visitor sees an error and no entry, notification or confirmation is created.
- Pre-flight payload validation. The payload is checked against the Hubspot form definition before it is sent. Hubspot answers a submission carrying an invalid dropdown option with
HTTP 200and then discards it, so such a submission would otherwise vanish with no error raised anywhere. - Full request tracing. Every submission writes its payload and Hubspot's response to
wp-content/debug.log. - Correct value shaping for checkbox, multi-select, consent, list, date and multi-input (Name, Address) fields, including boolean coercion for Hubspot
single_checkboxproperties. - Conversion page recorded. The page URL and title are sent with every submission, populating Hubspot's own Conversion page column.
- Cached form definitions (15 minutes) so the form editor does not call the Hubspot API once per field.
Scope boundaries
This plugin does not:
- install or manage the Hubspot tracking script (use Hubspot's own plugin for that);
- create or update Hubspot records through the CRM API — it submits to a Hubspot form, and Hubspot decides what records result;
- retry failed submissions or queue them for later;
- map a single Gravity Forms multi-input field (Name, Address) to more than one Hubspot property — the sub-values are joined into one value.
How it works
Two independent Hubspot endpoints are used:
| Purpose | Endpoint | Auth |
|---|---|---|
| Read a form's field list (admin) | https://api.hubapi.com/marketing/v3/forms/{formId} |
Private App bearer token |
| Submit an entry (front end) | https://api.hsforms.com/submissions/v3/integration/submit/{portalId}/{formGuid} |
None |
Submission runs on the gform_validation filter, so a Hubspot rejection fails validation and stops the form. A success is recorded as a note on the saved entry via gform_after_submission.
Prerequisites
| Requirement | Version | Notes |
|---|---|---|
| WordPress | 6.0+ | [ASSUMPTION] No minimum is enforced in code; 6.0 reflects the readme.txt "Requires at least". |
| PHP | 8.0+ | Declared in the plugin header. |
| Gravity Forms | 2.5+ | Enforced at runtime; below this the plugin refuses to load and shows an admin notice. |
Required accounts and credentials
| Credential | Purpose |
|---|---|
| Hubspot Portal ID | Identifies the Hubspot account in the submission URL. |
| Hubspot Private App access token | Reads form definitions from the Marketing Forms v3 API. Requires the forms scope. |
Both are entered in the WordPress admin and stored as options. Hubspot API keys (
hapikey) are no longer accepted by Hubspot and are not supported.
Never commit credentials. No environment variables are required — configuration lives in the WordPress options table.
Installation
Via Composer (recommended for Klyp projects)
The repository ships no composer.json, and its tags are named v.1.0.5 / v.1.0.4, which Composer cannot parse as versions — so a plain vcs repository cannot load it. Declare the release inline instead:
{
"repositories": [
{
"type": "package",
"package": {
"name": "klyp/klyp-gf-to-hubspot",
"version": "1.0.5",
"type": "wordpress-plugin",
"dist": {
"type": "zip",
"url": "https://github.com/klyp/klyp-gf-to-hubspot/archive/refs/tags/v.1.0.5.zip"
},
"source": {
"type": "git",
"url": "https://github.com/klyp/klyp-gf-to-hubspot.git",
"reference": "v.1.0.5"
},
"require": { "composer/installers": "^2.0" }
}
}
],
"require": {
"klyp/klyp-gf-to-hubspot": "1.0.5"
}
}
composer update klyp/klyp-gf-to-hubspot
With composer/installers and a type:wordpress-plugin installer path, the plugin lands in wp-content/plugins/klyp-gf-to-hubspot/.
[ASSUMPTION]The snippet pins1.0.5because that is the newest published tag. Version 2.0.0 is not yet tagged — see Release Process. Bump both theversion/referencefields and the constraint oncev2.0.0exists.
Manual
cd wp-content/plugins
git clone git@github.com:klyp/klyp-gf-to-hubspot.git
Or upload the plugin directory to wp-content/plugins/klyp-gf-to-hubspot/.
Configure
- Activate Klyp Gravity Form to Hubspot in Plugins.
- In Hubspot, create a Private App (Settings → Integrations → Private Apps) with the
formsscope and copy its access token. - In WordPress, go to Settings → Klyp Gravity Form to Hubspot and enter the Hubspot Portal ID and Private App access token.
Verify
- Open a Gravity Form → Form Settings → Hubspot Settings. Enter the Hubspot form GUID and save.
- Re-open the form editor and select any field. Under Advanced, the Hubspot field to map dropdown should list the Hubspot form's properties. If it shows an error notice instead, the token or form GUID is wrong.
- Submit the form and confirm
wp-content/debug.logcontains a matchingklyp-gf-to-hubspot: entry ... response HTTP 200line.
Usage
Mapping a form
- Form Settings → Hubspot Settings — enter the Hubspot Form ID (GUID) and save. Saving is required before the field lists can load.
- Optionally set Email field used in gravity form and Email field used in Hubspot. This guarantees the email address reaches Hubspot even when the Gravity Forms email field carries no mapping of its own.
- In the form editor, select a field → Advanced → Hubspot field to map.
Supported field types: checkbox, consent, date, email, hidden, multiselect, name, number, phone, radio, select, text, textarea, time, website.
Value handling
| Gravity Forms field | Sent to Hubspot as |
|---|---|
| Checkbox | Selected option values, ; delimited |
| Multi Select | JSON decoded, ; delimited |
| Consent | true / false |
| Date | YYYY-MM-DD (as stored in the entry) |
| List | Flattened, ; delimited |
| Name / Address | Non-empty sub-values joined with a space |
Any field mapped to a Hubspot single_checkbox |
true / false, always sent |
Two Gravity Forms fields mapped to the same Hubspot property collapse into one value (last one wins) rather than producing a duplicate-field error.
Failure behaviour
A Hubspot failure fails validation and blocks the submission. Where Hubspot names the property it rejected, the error is shown on the Gravity Forms field mapped to it; otherwise a generic message appears above the form. Technical detail always goes to wp-content/debug.log, and to the Gravity Forms log when Gravity Forms logging is on.
If the Hubspot field list cannot be loaded, the pre-flight check is skipped rather than blocking every submission — Hubspot's own response then decides the outcome.
Conversion page
The page the form was submitted from is sent as pageUri, with its title as pageName. This is what fills Hubspot's Conversion page column; a custom property cannot, because that column reads only the submission context.
Hubspot discards a submission whose page URL is on a domain the portal does not recognise. It answers HTTP 200 and then records nothing at all — no contact, no submission, no error. A local development host is the usual case, since the domain is not publicly reachable and the portal has never seen it. Withhold the page context there so submissions still arrive:
add_filter('klyp_gftohs_send_page_context', '__return_false');
pageName falls back to the URL path when the page is not a post, so the column is never blank. The visitor's hutk tracking cookie and IP address are sent regardless of this setting.
Caching
Hubspot form definitions are cached for 15 minutes. Clear them with the Clear cached Hubspot fields button on the settings screen after changing a form in Hubspot.
Filters
| Filter | Default | Purpose |
|---|---|---|
klyp_gftohs_send_page_context |
true |
Send pageUri / pageName — this is what populates Hubspot's Conversion page column. Return false on an environment whose domain the portal cannot see: Hubspot discards a submission whose page URL is on an unrecognised domain, answering HTTP 200 and recording nothing. |
klyp_gftohs_error_message |
generic message | Wording shown above the form when a failure cannot be attributed to a field. |
klyp_gftohs_mappable_field_types |
see list above | Which Gravity Forms field types get the mapping setting. |
klyp_gftohs_submission_payload |
payload array | Modify the payload before it is sent. |
klyp_gftohs_api_base |
https://api.hubapi.com/ |
Override the authenticated API base URL. |
// Local development: the portal cannot see this domain, so withhold the page
// context and let the submission through without a conversion page.
add_filter('klyp_gftohs_send_page_context', '__return_false');
Project Structure
klyp-gf-to-hubspot/
├── klyp-gf-to-hubspot.php Plugin header; Gravity Forms version gate; loads inc/
├── inc/
│ ├── hubspot-api.php klypHubspot client — field lookup, payload building,
│ │ validation, submission, logging
│ ├── hubspot.php Gravity Forms admin UI — form settings and the per-field
│ │ mapping control
│ ├── gf.php Submission handling on gform_validation; error surfacing
│ ├── settings.php Settings page registration, sanitising, cache flushing
│ └── settings-page.php Settings screen markup
├── tests/
│ ├── bootstrap.php WordPress + Gravity Forms stubs
│ └── test-hubspot-api.php Assertions for the API client and payload building
├── assets/js/main.js Reserved admin asset (currently unused)
├── readme.txt WordPress plugin readme
└── README.md This file
Development Setup
git clone git@github.com:klyp/klyp-gf-to-hubspot.git
cd klyp-gf-to-hubspot
There is no build step and no dependencies to install — the plugin is plain PHP. Symlink or copy the directory into a WordPress install's wp-content/plugins/ to work on it.
Coding standards
PSR-12 with the WordPress exception of snake_case for variables and function names; 4-space indent; PHPDoc on functions and classes; no closing ?> in pure-PHP files.
[ASSUMPTION]Nophpcs.xmlships with this repository, so standards are stated rather than enforced. Adding one would make them checkable.
Branching
Klyp promotion flow: feature branch → release-develop → develop (first review), and master → release-master → master (second review). Branches present here are develop, master and release-master. Commits follow Conventional Commits (feat, fix, perf, chore, docs, test, security).
Testing
The API client and payload building are covered by a standalone suite that stubs WordPress and Gravity Forms, so no WordPress install or database is needed:
php tests/test-hubspot-api.php
46 passed, 0 failed
It exits non-zero on failure, so it can be wired into CI as-is. Run it with strict error reporting to catch deprecations:
php -d error_reporting=E_ALL tests/test-hubspot-api.php
Coverage includes payload building per field type, the email guarantee, context handling, Hubspot error parsing, field discovery and caching, boolean checkbox coercion, and pre-flight option validation.
[ASSUMPTION]No CI configuration ships with this repository and no coverage tool is configured, so no build or coverage badge reflects a real pipeline.
Read the full README on GitHub →
Releases
These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.