APIs & Integrations

GGodlewski
Member

Inconsistency between API and UI regarding email subscription status

SOLVE

Hello there!

 

I recently discovered an inconsistency between what the Contacts UI says about the email subscriptions for my contacts vs the information returned from the API. I think this was working fine some time ago and then went broken.

 

Steps to reproduce:

 

- I create a contact via the API

- I check the contact in HubSpot UI, looking at "Communication Subscriptions", when clicking for the details I see that for all of my subscriptions the UI says "Not Specified".

- I use the JS SDK to get the communication preferences via the status API (example below).
- For each of my subscriptions the API response says that the user is subscribed.

 

Expected result:

The information exposed in the UI and via the API is consistent and I can see via the API which of the subscriptions the user is subscribed to.

 

Pain point: Effectively I'm not able to programatically establish the actual subscription status.

Snippet: Reproduction code

const client = new HubspotClient({
accessToken: ACCESS_TOKEN,
});

(async function reproduce() {
const response =
await client.communicationPreferences.statusApi.getEmailStatus(EMAIL);

response.subscriptionStatuses.forEach((status) =>
console.log(
"- %s (%s from %s)",
status.name,
status.status,
status.sourceOfStatus,
),
);
})().catch(console.error);

 

- EAP Development Updates (SUBSCRIBED from SUBSCRIPTION_STATUS)
- Marketing (SUBSCRIBED from SUBSCRIPTION_STATUS)
- Customer Service Communication (SUBSCRIBED from SUBSCRIPTION_STATUS)
- EAP Product Launches and Updates (SUBSCRIBED from SUBSCRIPTION_STATUS)
- EAP Product Research and Sruveys (SUBSCRIBED from SUBSCRIPTION_STATUS)
- Product Updates (SUBSCRIBED from SUBSCRIPTION_STATUS)

 

0 Upvotes
1 Accepted solution
GGodlewski
Solution
Member

Inconsistency between API and UI regarding email subscription status

SOLVE

I can share the solution which I developed that aligns with your recommendation. For other developers out there: if you want to check if the `SUBSCRIBED` is really valid, you should check the other field of the status called `legalBasis`. If it's `null` this means that the value returned as the status name is the default `SUBSCRIBED`.

In form of a snipped:

const isReallySubscribed  = status.name === "SUBSCRIBED" && status.legalBasis !== null;

View solution in original post

0 Upvotes
2 Replies 2
GiantFocal
Top Contributor | Gold Partner
Top Contributor | Gold Partner

Inconsistency between API and UI regarding email subscription status

SOLVE

Hi @GGodlewski,

 

The “Not Specified” status in the UI often appears for contacts created through the API because, by default, no explicit subscription action has been taken in the UI. However, the API might return them as “SUBSCRIBED” since no opt-out is recorded.

 

Here’s what’s happening:

  • UI: “Not Specified” means there’s no explicit record of the user subscribing or unsubscribing.
  • API: If there’s no opt-out, the API often interprets the status as “SUBSCRIBED” (especially for new contacts created via API).

What can you do:

  1. If you need true alignment, you’ll want to explicitly set the subscription status for each contact (either via API or UI). This way, both the UI and API will reflect the same, explicit status.
  2. For programmatic workflows, consider treating “SUBSCRIBED” from the API and “Not Specified” in the UI as functionally equivalent, unless you require explicit consent records for compliance purposes.
Glad I could help.
Solving HubSpot puzzles is what we do.
Ernesto // GiantFocal


Found this answer helpful?
Marking it as the solution helps both the community and me - thanks in advance!
0 Upvotes
GGodlewski
Solution
Member

Inconsistency between API and UI regarding email subscription status

SOLVE

I can share the solution which I developed that aligns with your recommendation. For other developers out there: if you want to check if the `SUBSCRIBED` is really valid, you should check the other field of the status called `legalBasis`. If it's `null` this means that the value returned as the status name is the default `SUBSCRIBED`.

In form of a snipped:

const isReallySubscribed  = status.name === "SUBSCRIBED" && status.legalBasis !== null;
0 Upvotes