Skip to content
Back to Resources
Guide

Mailchimp API: Campaign Report Deliverability and Bounce Rate

Skopx Team
August 5, 2026
8 min read

The Mailchimp Marketing API does not return a bounce rate for your campaign. GET /3.0/reports/{campaign_id} gives you raw counts, and you calculate the rate yourself: (bounces.hard_bounces + bounces.soft_bounces + bounces.syntax_errors) / emails_sent. The one field in that payload literally named bounce_rate lives inside industry_stats, and it is the benchmark for your industry, not your campaign. Reading it as your own number is the single most common mistake in Mailchimp reporting integrations, and it is silent: the value looks plausible, so nobody checks.

Deliverability in the same payload works the same way. Successful deliveries are emails_sent minus all three bounce types. There is no delivered field on the campaign report object, though there is one per domain on GET /reports/{campaign_id}/domain-performance, which is the endpoint you actually want when you are diagnosing a deliverability problem rather than counting it.

The request

Authenticate with HTTP Basic (any username, API key as the password) or an OAuth bearer token. The base URL carries your data center, which is the suffix on your API key after the dash, for example us19.

curl -u "anystring:$MC_API_KEY" \
  "https://us19.api.mailchimp.com/3.0/reports/42694e9e57?fields=id,campaign_title,emails_sent,send_time,bounces,abuse_reports,unsubscribed,opens,clicks"

The fields parameter is not cosmetic. The full report object carries timeseries data, ecommerce blocks, A/B split results and share URLs. Trimming it cuts response size by an order of magnitude on high volume campaigns, which matters when you are pulling hundreds of reports.

An illustrative trimmed response:

{
  "id": "42694e9e57",
  "campaign_title": "March newsletter",
  "emails_sent": 48210,
  "abuse_reports": 6,
  "unsubscribed": 91,
  "bounces": { "hard_bounces": 412, "soft_bounces": 233, "syntax_errors": 5 },
  "opens": { "opens_total": 30112, "unique_opens": 18904, "open_rate": 0.3975 },
  "clicks": { "unique_clicks": 2870, "click_rate": 0.0603 },
  "industry_stats": { "type": "Software and Web App", "bounce_rate": 0.0089 }
}

The denominator trap

Mailchimp does not use one denominator. Bounce rate is conventionally taken against emails sent, because a bounce is a failure to deliver and the delivered count already excludes it. Open rate and click rate are computed against successful deliveries. If you rebuild every rate against emails_sent for consistency, your numbers will not match the Mailchimp UI and someone will spend an afternoon on the discrepancy.

MetricFormula from the report payloadExample
Total bounceshard + soft + syntax_errors650
Bounce ratetotal bounces / emails_sent1.35%
Hard bounce ratehard_bounces / emails_sent0.85%
Successful deliveriesemails_sent minus total bounces47,560
Delivery ratedeliveries / emails_sent98.65%
Open rateunique_opens / deliveries39.75%
Complaint rateabuse_reports / deliveries0.013%
Unsubscribe rateunsubscribed / deliveries0.19%

One more unit trap: open_rate and click_rate come back as fractions like 0.3975, while several *_pct fields on other report endpoints read as values you will want to verify before multiplying by 100 in your own code. Recompute from raw counts wherever the counts are available and the ambiguity disappears.

Hard, soft and syntax errors are three different problems

A hard bounce is a permanent rejection: the mailbox does not exist, the domain does not resolve, the server refuses the address outright. Mailchimp cleans these contacts immediately, moving them to cleaned status so they are excluded from future sends. That is why hard bounce rate on a healthy, regularly mailed list should be very low. A spike means new addresses entered the list, which points at an import, a form without validation, or a CRM sync.

A soft bounce is temporary: full mailbox, message too large, server unavailable, greylisting, or a reputation-based deferral. Mailchimp retries, and an address that soft bounces repeatedly across sends eventually gets cleaned as well. A soft bounce spike concentrated on one receiving domain is usually a reputation signal rather than a list quality signal, and that distinction changes what you do next.

A syntax error means the address failed format validation before it was ever sent. Small numbers are noise. Anything meaningful indicates a data path that is writing garbage into your list, and the fix belongs upstream, not in Mailchimp.

To get the actual addresses, use GET /reports/{campaign_id}/sent-to, where each recipient record carries a status distinguishing sent from hard and soft bounces, or GET /reports/{campaign_id}/email-activity, which returns a per subscriber event stream including bounce events with their type. Email activity is one record per recipient and gets very large. Use the since parameter and paginate with count (maximum 1000) and offset. Cross referencing the bounced addresses with GET /lists/{list_id}/members?status=cleaned tells you how much of your list has already been burned.

Domain performance is where deliverability actually shows

A 1.35% blended bounce rate tells you nothing about cause. GET /reports/{campaign_id}/domain-performance breaks the same send down by recipient domain, returning emails_sent, bounces, delivered, opens, clicks and unsubs for each. Same campaign as above:

DomainSentBouncesBounce rateOpen rate
gmail.com21,400960.45%42.1%
yahoo.com6,100711.16%33.4%
hotmail.com / outlook.com5,300621.17%28.9%
Other15,4104212.73%41.0%

Now the number is actionable. The consumer mailboxes are fine. Nearly two thirds of the bounces sit in "other", which on a B2B list means corporate mail servers, and that pattern almost always traces to departed employees at customer accounts rather than to your sending reputation. The opposite shape, where Gmail bounces climb while everything else holds steady, is a reputation problem and calls for authentication checks and Google Postmaster Tools, not list hygiene.

Pulling many campaigns without hitting the rate limit

GET /reports returns all campaign reports and accepts count up to 1000, offset, since_send_time, before_send_time and type (regular, plaintext, absplit, rss, variate, automation). Combine it with fields scoped to the array, for example fields=total_items,reports.id,reports.send_time,reports.emails_sent,reports.bounces, and one request gives you a full bounce trend.

Mailchimp allows 10 simultaneous connections per API key and answers excess requests with a 429. Parallelising 50 report fetches will fail. Run a small worker pool with exponential backoff, or use the batch endpoint: POST /3.0/batches accepts a list of operations, returns a batch ID immediately, and you poll GET /3.0/batches/{batch_id} until the status is finished, then download the results archive.

What bounce rate does not tell you

Bounce rate measures rejection. It says nothing about whether the accepted mail reached an inbox or a spam folder, and those are the messages that quietly kill campaign performance. Three gaps are worth knowing about.

Complaint rate is the metric large mailbox providers act on. Google and Yahoo's bulk sender requirements ask senders to stay below a 0.3% spam complaint rate, with a lower figure as the practical target, alongside SPF and DKIM authentication, a DMARC record, and one-click list unsubscribe support. Mailchimp's abuse_reports count only captures complaints from providers that operate a feedback loop, and Gmail does not offer per message complaint data, so abuse_reports systematically understates your true Gmail complaint rate. Google Postmaster Tools is the only place to see it.

Open rate stopped being a clean deliverability proxy once Apple Mail Privacy Protection began prefetching tracking pixels. Inflated and unreliable opens are exactly why teams lean harder on bounce rate, but bounce rate cannot see spam foldering at all.

SignalWhat it provesWhere it lives
Bounce rateThe receiving server refused the message/reports/{id}
Per domain bouncesWhether the cause is list quality or reputation/reports/{id}/domain-performance
Complaint rateRecipients marked you as spam/reports/{id} plus Postmaster Tools
Inbox placementAccepted mail reached the inboxNeither, requires seed testing

A triage sequence that works

  1. Pull the report, compute total bounces over emails_sent, and split hard from soft.
  2. If hard bounces dominate, check what entered the list since the last send. Import, form, or sync.
  3. If soft bounces dominate, pull domain performance and look for concentration in one receiver.
  4. Confirm SPF, DKIM and DMARC pass on the sending domain before touching anything else.
  5. Pull the bounced addresses from sent-to and reconcile them against your CRM, so the same records do not resurface on the next sync.

When the answer is not in Mailchimp

Step five is usually where reporting stops and manual work starts. The bounce list is in Mailchimp, the accounts those addresses belong to are in your CRM, the import that introduced them was discussed in Slack, and suppressing them properly means writing back to a system that is not the one holding the report. Skopx connects to Mailchimp alongside your CRM, your warehouse and your messaging tools, so you can ask for the bounced addresses from the last send matched to their account owners in one question, and build a small internal app that shows the breakdown and puts a suppress button next to each record for a person to click.

Share this article

Skopx Team

The Skopx engineering and product team

Related Articles

Guide

Free Data Analysis Tools: What Each One Actually Does Well

The honest short answer: for most work, four free tools cover almost everything. Google Sheets for anything under about 100,000 rows where you need collaborators. Python with panda

10 min readAug 5, 2026
Guide

Affordable Business Intelligence: What You Actually Pay For, and What You Can Skip

The honest answer to "what is an affordable business intelligence solution" is that there are three real price tiers, and most companies overshoot by one. Under $20 per user per mo

9 min readAug 5, 2026
Guide

HR People Analytics Software: What It Does, What to Buy, and Where It Breaks

HR people analytics software connects to your HRIS, ATS, payroll, and engagement survey tools, keeps a dated history of every employee record, and turns that into headcount, attrit

9 min readAug 5, 2026
Guide

Insurance Business Intelligence Software: What It Is and How to Choose

Insurance business intelligence software is reporting and analytics tooling that reads from your policy administration, claims, billing and agency management systems and turns thos

9 min readAug 5, 2026
Guide

Asana Data for Analysis: Getting Numbers Out That Actually Mean Something

The fastest way to get Asana data into a form you can analyze is one of four routes, ranked by effort: CSV export from any project or search view (Project menu, Export/Print, CSV),

9 min readAug 5, 2026
Guide

How AI Is Changing Data Analytics

AI is changing data analytics in five concrete ways: it has replaced the SQL-writing step with plain-English questions, it has moved the bottleneck from producing charts to trustin

8 min readAug 5, 2026

Stay Updated

Get the latest insights on AI-powered code intelligence delivered to your inbox.