HubSpot Forms API fix

Fix HubSpot Forms API context with pageUri, pageName and hutk.

The `context` object does not usually cause the whole submission to fail, but bad page data makes attribution, page history and debugging much harder.

Fast checklist

  • Send a full public URL in `context.pageUri`.
  • Send a readable page title in `context.pageName`.
  • Only include `hutk` when the visitor has a `hubspotutk` cookie.
  • Do not hard-code one visitor cookie for every lead.
  • Keep context values as plain strings.

Correct context shape

Start with a small context object. `pageUri` should describe where the visitor submitted the form, while `pageName` should be the page label you would expect to see later.

{
    "fields": [
        {
            "name": "email",
            "value": "developer@example.com"
        }
    ],
    "context": {
        "pageUri": "https://example.com/contact",
        "pageName": "Contact"
    }
}

Add hutk only when it exists

`hutk` is the value from the visitor's `hubspotutk` cookie. If that cookie is missing, send `pageUri` and `pageName` without inventing a tracking value.

$payload = [
    'fields' => [
        [
            'name' => 'email',
            'value' => $email,
        ],
    ],
    'context' => [
        'pageUri' => 'https://example.com/contact',
        'pageName' => 'Contact',
    ],
];

if (!empty($_COOKIE['hubspotutk'])) {
    $payload['context']['hutk'] = trim((string) $_COOKIE['hubspotutk']);
}

Common context mistakes

1. Sending a relative pageUri

A value like `/contact` is easier for humans to read, but a full absolute URL is safer for attribution and debugging.

"context": {
    "pageUri": "/contact",
    "pageName": "Contact"
}

2. Reusing one hard-coded hutk

A copied cookie value can attach unrelated submissions to the wrong visitor. Read the current visitor cookie or omit `hutk`.

3. Sending empty strings

Empty context values do not help debugging. If you do not know the page name, use the URL path or a stable fallback like the form label.

WordPress context example

In WordPress, build `pageUri` from the current page when possible, and use the page title as `pageName`.

$page_uri = get_permalink();

if (!$page_uri) {
    $page_uri = home_url(add_query_arg([], $_SERVER['REQUEST_URI'] ?? '/'));
}

$payload['context'] = [
    'pageUri' => esc_url_raw($page_uri),
    'pageName' => wp_strip_all_tags(get_the_title() ?: 'Website form'),
];

if (!empty($_COOKIE['hubspotutk'])) {
    $payload['context']['hutk'] = sanitize_text_field(wp_unslash($_COOKIE['hubspotutk']));
}

Plain PHP context example

For a custom PHP form, use your known canonical page URL when you have it. If you build from server values, validate the host you expect before trusting it.

$page_uri = 'https://example.com/contact';

$payload['context'] = [
    'pageUri' => $page_uri,
    'pageName' => 'Contact',
];

if (!empty($_COOKIE['hubspotutk'])) {
    $payload['context']['hutk'] = trim((string) $_COOKIE['hubspotutk']);
}

Quick debugging flow

If a submission works but the contact has poor page attribution, paste the payload into the debugger and check the context warnings before changing field or consent code.

error_log(json_encode($payload['context'], JSON_PRETTY_PRINT));