Double opt-in via API Form submission

Hi,

i am already in contact with the hubspot support via e-mail and they said they dont have a solution and i should ask here.

I am a developer for one of my clients. Hubspot is new to me, maybe i just need a little hint. I am trying to get the following workflow:

  1. Custom form on website for newsletter (communication-preferences)
  2. Via API i call POST on /submissions/v3/integration/submit/{portalId}/{formGuid}
  3. User recieved double-opt-in email from hubspot
  4. After accepting, user is subcribed

i was using the POST with that body:

{
  "fields": [
    {
      "objectTypeId": "0-1",
      "name": "email",
      "value": "value of the email here"
    },
    {
      "objectTypeId": "0-1",
      "name": "hidden_check_field",
      "value": ""
    },
    {
      "objectTypeId": "0-1",
      "name": "lead_quelle",
      "value": "/"
    }
  ],
  "context": {
    "pageName": "home-footer",
    "pageUri": "/",
    "pageId": "abc-123d-adsfc-eewer",
    "sfdcCampaignId": ""
  },
  "legalConsentOptions": {
    "consent": {
      "consentToProcess": true,
      "text": "i consent",
      "communications": [
        {
          "value": false,
          "subscriptionTypeId": 86103169,
          "text": "I agree to receive marketing communications from Example Company."
        },
        {
          "value": false,
          "subscriptionTypeId": 780483031,
          "text": "I agree to receive marketing communications from Example Company."
        },
        {
          "value": false,
          "subscriptionTypeId": 5744496,
          "text": "I agree to receive marketing communications from Example Company."
        },
        {
          "value": false,
          "subscriptionTypeId": 2700298312,
          "text": "I agree to receive marketing communications from Example Company."
        }
      ]
    }
  }
}

And with that, i do recieve a double-opt-in mail from hubspot, but after accepting it, i can see through the endpoint crm/objects/2026-03/contacts/search the new user.

But through communication-preferences/2026-03/statuses/{subscriberIdString} (the subscriberIdString is the e-mail, in this example it is “value of the email here”) it tells me, that this subscriberidstirng has no communication preferences. And when my client looks into his hubspot account, he can confirm that this e-mail address has no communication preferences.

Anyway.. If i set the “value” in the POST body on “true”, i dont recieve a double-opt-in mail and the user is immediately set to “SUBSCRIBED” on all subscriptionTypedId.

Any idea?

Moderator note: The HubSpot Community is a public space. I have therefore edited your content for security & confidentiality reasons.

Hey @teafox and welcome, we are so glad to have you here!

Thanks for reaching out to the HubSpot Community!

To start with, I’d suggest to check out these resources:

Let’s invite our Top Experts to this discussion: Hey @Anton, @nickdeckerdevs1 and @Bortami do you have any insights to share with @teafox, please?

Thanks so much and have a wonderful day!

Bérangère

Hey @teafox,

there’s a setting for the DOI in the HubSpot settings, which should handle everything DOI related. If this should be off, it might be the case for you not getting the DOI email. Regardless if you trigger it via API call.

best,
Anton

I would separate two things here: form submission and subscription status. The form endpoint can create/update the contact and trigger DOI, but HubSpot will only write the subscription preference when the submitted communication consent is an opt-in for that subscription type.

In your payload the communication values are all false, so the contact is effectively saying “do not subscribe me to these types”. That can still produce the DOI email, but after confirmation there is no positive preference to store.

I would test with one subscription type first:

  1. Keep consentToProcess: true.
  2. Send only the newsletter subscriptionTypeId you want to opt in.
  3. Set that communication value to true.
  4. Make sure double opt-in is enabled for that form / subscription flow in the portal settings.
  5. After confirmation, check the preference endpoint again using the same email.

If value=true bypasses DOI in this portal, the remaining workaround is to let a native HubSpot form handle the subscription/DOI step, or submit the custom form without subscription consent and trigger a separate HubSpot-managed preference flow. Do not try to model “pending opt-in” by sending value=false; that represents a negative consent state, not pending consent.

Moderator note: While this solution may not address the original poster’s specific situation, it could be helpful for other community members facing similar challenges.

Thanks for your answers!

Yes, i tested with only one subscriptionTypesId with the same results. value=true bypasses the DOI in this portal. DOI is definetely turned on in hubspot.

A native HubSpot Form is not an option for my client because of the ui-design limitations.

We will try the separate hubspot-managed preference flow. I let you know if that worked.

Hey @teafox,

HubSpot forms are fully customizable in their look&feel.

If your client uses the legacy forms, you can easily disable the default HubSpot CSS by modifying the embed code from

<script charset="utf-8" type="text/javascript" src="//js-eu1.hsforms.net/forms/embed/v2.js"></script>
<script>
  hbspt.forms.create({
    portalId: "123456789",
    formId: "some-form-id",
    region: "eu1"
  });
</script>

to

<script charset="utf-8" type="text/javascript" src="//js-eu1.hsforms.net/forms/embed/v2.js"></script>
<script>
  hbspt.forms.create({
    portalId: "123456789",
    formId: "some-form-id",
    region: "eu1",
    css: ""
  });
</script>

adding css: ""to the embed form disables the default HubSpot styling and lets you completely overwrite everything with CSS in your external tool. There are tons of more options what you can do to legacy forms :wink:

For the new forms (multistep), it’s a bit different, but also possible

  • First: enable the developer embed code option in the form
  • Add all the variables to your CSS in the external tool and modify it (let AI do it)

My recommendation is: If you got many forms on your external page/system and you can create custom/reusable building blocks or something similar, just use the embed code (new or legacy forms) and replace the form ID with a text input (not rich-text) set it up once and call it a day.

The form ID can be found in the URL of the form in HubSpot

The URL structure differs from the legacy to new forms, but the structure is as following

New forms:

https://app-eu1.hubspot.com/forms/THIS-IS-THE-HUBID/new-editor/1bf13a8d-39aa-46ce-9166-db8565e4afa7

The last part is the form_id.

For legacy forms it’s following structure:

https://app-eu1.hubspot.com/forms/THIS-IS-THE-HUBID/editor/f454eaf8-05f3-492c-b7fb-3478c04fa7e6/edit/form

the part between /editor/ and /edit/ is the form_id.

If you should build the external reusable block, your client can simply build the form in HubSpot, copy the ID from the URL and paste it into his system. Done :slight_smile:

edit:
The codes above state that the region is “eu1”. If the clients portal is located/hosted in the US, change it to “na1” (north america 1). If it’s on the European server, ignore this

best,
Anton