Solved

Checking if a user is suppressed?

  • 29 March 2022
  • 9 replies
  • 493 views

Badge +3

Howdy!

How do I check if a user is globally suppressed with an API call?

From the documentation it looks like the /api/v2/list/{list_id}/get-list-subscription should be able to handle this but the user is still returned even though the user is globally suppressed :/

The api endpoint /api/v1/people/exclusions sees the user as being globally but this endpoint will not scale well to find if a single user is unsuppressed as the number of users grows.

And the $consent array on the profile object appears to be useless for this.

What is the correct way of solving this?

icon

Best answer by Chuck Curtis 1 April 2022, 17:35

View original

9 replies

Userlevel 7
Badge +60

Hey @Henrik Sommerland,

Great question!

Based on your description, it sounds like the https://a.klaviyo.com/api/v2/list/{list_id}/get-list-subscriptions endpoint should be able to allow you to accomplish your goal. This endpoint is meant to check if one or more emails are in a given list and are not suppressed. 

This means, that users who are globally suppressed should not be returned when hitting that endpoint. Globally suppressed profiles are denoted by a red circle and “X” in their profiles under Channel Details

I would also keep in mind when making a GET request to the https://a.klaviyo.com/api/v1/people/exclusions endpoint, that this returns all users who are either globally suppressed or have unsubscribed from a list. The distinction here, is that users may have unsubscribed from a specific list, but are not globally suppressed. 

Globally suppressed profiles are profiles ones that will no longer receive emails from you at all. Whereas users who have unsubscribed from a specific list would still continue receiving marketing emails from you; just not ones sent to the list they unsubscribed from. 

From your explanation, I would assume that this profile you’re testing sounds like they may have unsubscribed from a specific list but are not globally suppressed. This would explain why they are still being returned when making a POST request to the https://a.klaviyo.com/api/v2/list/{list_id}/get-list-subscriptions endpoint as well as a GET request to the https://a.klaviyo.com/api/v1/people/exclusions endpoint. 

If this user was truly globally suppressed, they should only be returned as part of the https://a.klaviyo.com/api/v1/people/exclusions endpoint.

In addition, the $consent property would typically be used to identify the types of consent a subscriber has given. The available array values for this property are limited to “email”, “web”, “mobile”, “sms”, and “directmail”. This property would not actually relay if a user is suppressed or not though. 

I would also suggest taking a look at some of the available resources in our Klaviyo Help Center to learn more about suppressions. I’ve included a few below for your convenince:

If you’re still having troubles, I think it would be beneficial to share some screenshots of the Klaviyo profile you’re testing with, providing the calls you’re making, and sharing more details on the goal you’re trying to accomplish as other Community members may have a solution!

David

Badge +3

Hi!

So I’m running this code to test the get-list-subscription endpoint:

email = "asdfg1234asd@mailinator.com"

meh = post(
"https://a.klaviyo.com/api/identify",
json={
"token": private_key,
"properties": {
"$email": email,
},
},
)

if meh.json() == 0:
print("identify call failed")
quit()

client.ListsSegments.subscribe(list_id="XnZYXB", body={"profiles": [{"email": email}]})
client.ListsSegments.exclude_globally(email=email)

profiles = client.ListsSegments.get_list_subscriptions(
"XnZYXB", body={"emails": [email]}
)

if email in [p["email"] for p in profiles]:
print("The user is still considered subscribed")

exclusions = client.ListsSegments.get_global_exclusions()
if email in [e["email"] for e in exclusions["data"]]:
print("The user is considered globally excluded")

Where the email is not in the system and “XnZYXB” is a single-optin list.

When I run this it will always find the user in the list and print `The user is still considered subscribed` and that the user is considered globally excluded, and the user appear as suppressed in the gui
 

 

And regarding the unsubscribing from lists, this statement is a bit confusing as:

Whereas users who have unsubscribed from a specific list would still continue receiving marketing emails from you; just not ones sent to the list they unsubscribed from. 

Given that the behavior can be configured both on a list level or the account level. 


And using the get global exclusions endpoint to determine if a user is opted out is not feasible as the list of excluded users might grow large over time. 

We managed to solve the handling and tracking of optin state by looking at the metric events for a user to determine if a user has opted out or not. But it feels a bit like a hack.

Userlevel 1
Badge +1

Hi Henrik,

Thank you for the additional details here!  Based on your code example, it looks like you’re using Klaviyo’s Python SDK - would that be correct?

In any case, you could confirm that a profile is suppressed by created a Segment that lists all profiles in Klaviyo that are currently suppressed for email.  Then, instead of

profiles = client.ListsSegments.get_list_subscriptions( "XnZYXB", body={"emails": [email]} )

you would use

profiles = client.ListSegments.get_members(“SEGMENT_ID”, body={“emails”: [email]} )

and then profiles would contain the profile if it is suppressed.

From there, you would reverse the logic of the last two parts, so that if the profile is in profiles, then that would mean that it is suppressed.  If the profile is not found in profiles, that would mean that the profile is not suppressed.
I hope this helps!

Badge +3

Yes I’m using the python SDK.

One of my initial attempts after realizing that there is no way to easily check if a dude is suppressed was to use a segment to tack suppressed users. But the issue with segments is that they appear not to be immediately updated.

client.ListsSegments.exclude_globally(email=email)

profiles = client.ListsSegments.get_segment_members(
supp_segment, body={"emails": [email]}
)

if email in [p["email"] for p in profiles]:
print("The user was in the excluded segment")

This for example will not consider the user to be in the segment. But if rerun with she same email a couple of minutes later it will find the user in the segment.

Working with metric events instead has the effect of being essentially immediately updated.

But I still wonder why a call to get_list_subscriptions does not work as advertised :/

Userlevel 1
Badge +1

Hi Henrik,

Thank you for the additional details!

I had to check with our dev team to confirm the expected behavior of the /v2/list/{list_id}/get-list-subscriptions (ie ListsSegments.get_list_subscriptions) endpoint and they confirmed that it is expected with this version of the API that the endpoint will return the profiles that are on the list, even if the profiles are globally suppressed for email. The endpoint will not return the profile if it is not on the list.

We acknowledge that this is not intuitive and we will be addressing this in future iterations of the Klaviyo APIs. I've also shared this with our documentation team to clarify the confusion well.

As for the suppressed segment timing, there can be a delay of up to 15 minutes between when a profile is added to a segment, and when the APIs will reflect the new addition. Though it is a great workaround!

As you mentioned, using the Metrics API will generally not have this same lag period.

Badge

It would be super helpful if Klaviyo developers would add an email filter on the global exclusions list. 

I tried using Henrik’s metrics workaround to get the subscribe/exclusion status, but there’s no event registered when a profile is excluded manually from the Klaviyo admin, so as far as I can tell there’s still no reliable way to tell if someone’s excluded other than looping every single global exclusion which is not really a reasonable thing to do.

It seems like the Klaviyo API is crippled without this basic ability to tell if a user is subscribed or not.

Badge

Hi,

please add another status field to the result of getListSubscriptions() showing the status subscribed / unsubscribed.
I've now done it with profileMetricTimeline() and the id of the user as well as the id of the subscribed and unsubscribed events. If the subscribed event timestamp is > the unsubscribed event, I consider the email subscribed. But I don't know if the result is correct and I may need 2 more function calls.

Badge

Hey @David To,

I’ve been checking out the new APIs looking to see if this old problem of not being able to tell if a specific user has been suppressed has been solved. I’m not seeing yet. Am I missing it?

Userlevel 7
Badge +60

Hey @friendscottn,

You’re not missing anything. Checking in with our dev team, it looks like this behavior is still present in the new API. Our team is aware of this behavior and still working on various aspects of improving both the existing and our new API.

I’ll provide an update when I hear any news from our team!

Thanks for being a part of the Klaviyo Community!

David

 

Reply