Home Blog Resume Contact Ask AI About Me
Home/Blog/How to Find Which Klaviyo Segment Is Burning …
How toKlaviyoKlaviyoDeliverabilitySegmentation

How to Find Which Klaviyo Segment Is Burning Your Domain

13 min readBy Miloš Mitrović

A spam complaint spike has a source, and the source is almost always one cohort buried inside a much larger send. The short answer is that you cannot query it directly: Google reports a spam ratio per authenticated domain per day and never names a complainer, and Klaviyo's metric aggregation has no segment dimension at all. You find the cohort by joining two things neither vendor will join for you, the per-profile complaint events from the providers that do name complainers, and a deliberately staggered send calendar that makes each day's Gmail number belong to exactly one cohort. The procedure below takes about two weeks of calendar discipline and produces a defensible answer instead of a guess.

Key takeaways

  • The short answer: convict a segment with per-profile Marked Email as Spam events for Microsoft, Yahoo and the other feedback loops, and convict it at Gmail by isolating one cohort per send day and reading Postmaster's daily ratio.
  • Gmail's feedback loop is aggregated by Feedback-ID identifier and never identifies a recipient, so a Gmail complainer never arrives in Klaviyo as a profile-level event.
  • Klaviyo's /api/metric-aggregates endpoint accepts Campaign Name, $message, $flow, List, Inbox Provider, Email Domain and form_id in its by array, and nothing for segment. Segment attribution has to be rebuilt through the message.
  • The two denominators differ. Klaviyo divides complaints by recipients; Google divides user-reported spam by mail delivered to the inbox. Google's ratio therefore climbs as inbox placement degrades even when the raw complaint count is flat.
  • Google asks senders to stay under a 0.10% spam rate and to never reach 0.30%, and applies bulk sender rules above 5,000 messages a day to Gmail.
  • A Klaviyo account has one branded sending domain, and several accounts can be connected to the same one, so a shared subdomain makes the Postmaster number a portfolio number that no single brand can be blamed for.

What you need before you start

  • Klaviyo access at Owner or Admin level, because step one reads the account's domain settings and later steps change the send calendar.
  • A Klaviyo private API key scoped to metrics:read, events:read, profiles:read, segments:read and campaigns:read, and the revision: 2026-07-15 header on every call.
  • Google Postmaster Tools with the exact sending subdomain verified, plus an OAuth client holding https://www.googleapis.com/auth/postmaster.readonly if you want the numbers as data rather than as a chart.
  • Enough Gmail volume per send that Postmaster reports the day at all. Google withholds a day's figures when the message count is too low, to protect user privacy.
  • Somewhere to join two daily tables. A warehouse is better, a two-tab spreadsheet is enough.
  • Microsoft SNDS only if you own the sending IP. Registration is verified against the WHOIS abuse contact for the IP space, so a sender on an ESP's shared pool cannot register it, and Microsoft now ties the Junk Mail Reporting Program feed to an SNDS registration.

Isolate the segment driving your spam complaints

  1. Confirm what the reputation number actually covers. In Klaviyo, open Settings and then Domains, and read the branded sending domain, for example send.example.com. Google attaches domain reputation and the spam ratio to the DKIM-authenticated domain, so add that subdomain to Postmaster Tools rather than the root domain. An account can hold one branded sending domain for marketing, and separate domains for transactional and service mail each build their own reputation. If two brands are connected to the same subdomain, which Klaviyo permits with identical CNAME or NS records and a different TXT value per account, then every number you are about to collect is a pooled number. That is the same failure mode that makes portfolio-level Klaviyo revenue impossible to reconcile, arriving on the deliverability side instead of the reporting side. Separate the subdomains first or accept that you are diagnosing the group, not the brand.
  2. Pull the Gmail record as data. The Postmaster interface hides the precision you need. Call the API for the whole window instead, then keep the bounds rather than the point estimate, because Google labels the ratio as potentially inexact and publishes an explicit range alongside it.
    curl -s -H "Authorization: Bearer $POSTMASTER_TOKEN" \
      "https://gmailpostmastertools.googleapis.com/v1/domains/send.example.com/trafficStats?startDate.year=2026&startDate.month=6&startDate.day=1&endDate.year=2026&endDate.month=8&endDate.day=10"
    Keep userReportedSpamRatio, userReportedSpamRatioLowerBound, userReportedSpamRatioUpperBound, domainReputation, spfSuccessRatio, dkimSuccessRatio, dmarcSuccessRatio and deliveryErrors per day. domainReputation returns one of HIGH, MEDIUM, LOW or BAD. Rule out authentication before you go hunting for a segment: a dkimSuccessRatio below 1 on the days that spiked is a DNS problem wearing a list problem's clothes.
  3. Resolve the metric IDs, then build the Klaviyo side at the same daily grain. Metric IDs are scoped to the account, so GET /api/metrics first and record the IDs for Received Email and Marked Email as Spam. Then aggregate both at day grain, split by provider, so the Klaviyo figure is comparable to a Gmail-only number.
    POST https://a.klaviyo.com/api/metric-aggregates
    {"data":{"type":"metric-aggregate","attributes":{
      "metric_id":"AbC123",
      "measurements":["count"],
      "interval":"day",
      "by":["Inbox Provider"],
      "timezone":"America/New_York",
      "filter":["greater-or-equal(datetime,2026-06-01T00:00:00)",
                "less-than(datetime,2026-08-10T00:00:00)"]}}}
    Set timezone to the account's reporting timezone once and never change it mid-investigation. Postmaster reports on its own day boundary, and an unforced timezone mismatch will smear a one-day spike across two.
  4. Compare the two complaint rates and expect them to disagree. Klaviyo states its formula as the number of people who marked your email as spam divided by the number of recipients. Google divides user-reported spam by the mail that reached the inbox. As placement degrades, Google's denominator shrinks while Klaviyo's does not, so the Gmail ratio can double while the Klaviyo rate holds steady. Treat divergence between the two curves as evidence that placement is moving, and treat the Gmail curve as the one that decides your fate.
  5. Rank the sends before you rank the segments. Re-run the aggregation for Marked Email as Spam with "by":["$message"], then again with "by":["Campaign Name"] and "by":["$flow"]. You now know which messages carry the complaints. This is where most investigations stop, and it is not an answer, because a single campaign usually goes to one broad audience that contains every cohort you are trying to separate.
  6. Map each guilty message back to the audience it targeted. Call GET /api/campaigns?filter=equals(messages.channel,'email'), which refuses to run without that channel filter, and read audiences.included and audiences.excluded for every campaign on the spike days. Record send_strategy.method and send_options.use_smart_sending at the same time: a send with smart sending off is a send that reached people who had already been mailed that day. For flows, the audience is the trigger plus the flow filters, so read those from the flow itself. The output is a message-to-segment map, which is the join Klaviyo does not expose.
  7. Convict a segment using the providers that name complainers. Microsoft, Yahoo and several others return per-message complaint reports, and those become profile-level Marked Email as Spam events in Klaviyo. Pull them, then test the complainers against each candidate segment.
    GET /api/events?filter=equals(metric_id,'AbC123'),greater-or-equal(datetime,2026-07-27T00:00:00)&include=profile&page[size]=1000
    
    GET /api/segments/SEG123/profiles?filter=any(email,["[email protected]","[email protected]"])&page[size]=100
    Batch the complainer emails in groups of 100 against every candidate segment ID. Then compute complaint density per segment: complainers found in that segment divided by the profiles from that segment who were actually mailed in the window. Density is the number that convicts, not raw count. A 400,000-profile segment will always produce more complaints than a 20,000-profile one, and suppressing the wrong one costs revenue for nothing.
  8. For Gmail, stagger the calendar so each day belongs to one cohort. Gmail's feedback loop reports in aggregate against the first four colon-separated fields of the Feedback-ID header, in the form Feedback-ID: a:b:c:SenderId with a mandatory sender identifier of 5 to 15 characters, and a report only appears when an identifier carries enough mail and enough distinct user spam reports on that day. Your ESP owns that header, so the identifier is not yours to set. What you do own is the calendar. Define three or four cohorts by engagement recency, for example clicked in 30 days, opened in 90, opened in 365, and no engagement in 365. Send each cohort as its own campaign on its own day, with at least 24 hours of clear air and no flows retargeting the same people, and keep each cohort large enough in Gmail terms that the day is not suppressed. Postmaster's daily ratio then attributes itself. Two weeks of this replaces a year of speculation.
  9. Change exactly one thing, then hold still. Rank cohorts by density first and volume second, suppress or throttle the worst one, and change nothing else for 14 days. Simultaneously check the intake, because a cohort that generates complaints on its first send was usually acquired badly rather than fatigued: aggregate Subscribed to List with "by":["form_id"] and look for a form whose signups spiked and whose 30-day engagement is near zero. That is a bot or a mistyped-checkout problem, and no amount of segment tuning will fix it upstream of the form.

Which evidence source answers which question

Four sources overlap, and each one is silent on something the others cover. Reading them in the wrong order is why these investigations stall.

SourceGrainCoversCannot tell you
Postmaster Tools API, trafficStatsPer sending domain, per dayGmail only, DKIM-authenticated mail onlyWhich message, which cohort, which recipient. Low-volume days are withheld
Gmail feedback loop, Feedback-IDPer identifier, per dayGmail, above an undisclosed volume and complaint thresholdAnything about a recipient, and anything at all if your ESP sets the header
Klaviyo Marked Email as Spam eventsPer profile, per messageThe providers that return per-message reportsGmail complaints, which never become profile events
Klaviyo deliverability hubAccount level, top five providers by volumeScore, negative and positive engagement, bounce categoriesSegment-level rates, and any provider outside your top five

The cohorts that cause most of the damage

Across six Klaviyo accounts I have rebuilt, the same four cohorts account for nearly all of the complaint volume, and each leaves a different fingerprint.

CohortKlaviyo definitionFingerprint that convicts it
Reactivated dormant profilesNot in "Opened Email at least once in the last 365 days" and mailed in the last 30Complaints concentrate on the first send after a long silence, and hard bounces rise with them
An imported or inherited listProfiles with a Subscribed to List event on a single historical dateComplaint density many times the account average, spread evenly across every campaign
Form intake without real consentSubscribed to List grouped by form_id, joined to 30-day engagementSignup volume spikes, engagement stays near zero, and complaints start within days of signup
Over-mailed buyersReceived more than N messages in 7 days, with smart sending disabled somewhereComplaints follow send frequency rather than any list attribute, and open rates fall with each send

The fourth one deserves a caution. Flow overlap is the most common cause and the least visible, because each flow looks reasonable in isolation. A cart flow, a browse flow and a weekly campaign can all fire against the same shopper inside 48 hours without any single one of them looking aggressive. The fix is fewer, better-targeted messages rather than a harsher suppression rule, which is the logic behind rebuilding cart emails around what the shopper actually looked at.

Troubleshooting

  • Postmaster shows no data on the exact days you care about. Either the volume was too low and Google withheld the day, or the mail was not DKIM-signed with the domain you verified, or you added the root domain while Klaviyo signs with a subdomain. Check dkimSuccessRatio on a day that does report before assuming the tool is broken.
  • Complaints on a day with no campaign. Flows still ran, and a transactional or service subdomain may share the reputation you are watching. Aggregate Marked Email as Spam by $flow for that day, and confirm which subdomain signed each stream.
  • Per-profile complaint events are close to zero while Gmail's ratio is high. That is the expected shape when your list is Gmail-heavy. It is not evidence that complaints are low. Go straight to the staggered calendar in step eight.
  • Bounces and complaints rising together. Treat them as two problems. List verification reduces unknown-user bounces, and it does not reduce complaints, because a real person complaining is not an invalid address. It is also less decisive than vendors imply: when I verified a one-million-contact database in-house, SMTP-level verification was defeated on the majority of corporate addresses because Microsoft 365, Google Workspace and Proofpoint accept mail for any local part and reject later. Verification is list hygiene, not a deliverability cure.
  • Suppression drops revenue further than expected. You suppressed on count rather than density and removed a large, mildly noisy segment instead of a small, badly behaved one. Recompute density, restore the large segment at reduced frequency, and keep the small one suppressed.
  • The number improves and then decays again after four weeks. Something upstream keeps refilling the bad cohort. That is nearly always a form, a checkout capture with single opt-in, or a sunset rule that exists as a segment but was never wired into a flow that actually suppresses.

How to verify it worked

One good day proves nothing, and the reports that look most reassuring are the ones that move first. Hold the change for 14 days and check five things in this order.

  1. Postmaster userReportedSpamRatio below 0.001 for seven consecutive reported days, judged on userReportedSpamRatioUpperBound rather than the point estimate. Google's stated target is under 0.10%, with 0.30% as the line never to approach.
  2. domainReputation back to HIGH, and staying there through a full-file send rather than only through the small engaged sends you made while diagnosing. Reputation recovers slowly and regresses quickly, so the test is a normal week, not a cautious one.
  3. Complaint density recomputed per segment using the same query from step seven over the new window. The convicted cohort should no longer sit at the top, and no previously clean cohort should have taken its place.
  4. Klaviyo's deliverability hub agreeing with you. Open Analytics, then Deliverability, then Email, and read the negative engagement metrics card in the Reports tab with the message category filter set to Gmail. Confirm the account has moved out of its previous score band, where Klaviyo bands 0 to 49 as Poor, 50 to 74 as Fair, 75 to 89 as Good and 90 to 100 as Excellent, and confirm no high spam complaint rate alert remains open.
  5. Revenue per recipient on the retained cohorts, not total revenue. Total revenue falls when you suppress, by design. What must not fall is the value of the audience you kept. If revenue per recipient is flat or up while the complaint ratio is down, the suppression was correct and you can begin widening again in one cohort steps.

Write the whole thing down as a dated record: the cohorts, the send days, the ratios and the decision. The next time this happens, the diagnosis takes two days instead of two weeks, because the baseline already exists.

Sources

M
Miloš Mitrović
Revenue Operations & AI Automation

Have a question or a project?

Whether it is about this post or a system you want built, I'm happy to talk.

Get in touch

404

Post not found. It may have been moved or the link is incorrect.

← Back to the blog
Ask AI About Me
Clicking an assistant copies the prompt and opens it: ready to run in ChatGPT, Perplexity, and Grok; in Claude, Gemini, or Copilot press Ctrl+V (Cmd+V on Mac) to paste. Use Copy prompt for any other AI. The assistant reads my site, so it needs web access.
Summarize with AI
ChatGPT, Perplexity, and Grok open with the prompt ready to run. Claude, Gemini, and Copilot open a chat with the prompt copied; press Ctrl+V (Cmd+V on Mac) to paste. The full text is included, so it works even without web access.