Clean bounced emails from HubSpot and alert your team in Slack

When Customer.io reports a hard bounce or spam complaint, mark the contact as invalid in HubSpot and post a real-time summary to your marketing-ops channel.

Agentic Task
Customer.ioHubSpotSlack BotMarketingOperationsNotifications & AlertsData SyncEmail Automation

Build me an agent workflow that protects email deliverability by reacting in real time to Customer.io bounce and spam complaint events. The agent should clean up the matching HubSpot contact and alert our marketing-ops team in Slack.

Trigger: a Customer.io Reporting Webhook. I will configure the webhook in Customer.io to send `email_bounced` and `email_spammed` events to the workflow's webhook URL. Each request body will include the recipient email, delivery id, message id, the reason text, and a flag indicating whether the bounce is hard, soft, or a spam complaint.

Step 1: Parse the incoming webhook payload and pull out the recipient email, delivery id, message id, the raw bounce reason, and the bounce category (hard vs soft vs spam complaint).

Step 2: Classify the failure into one of: mailbox does not exist, domain rejected, policy or content block, spam complaint, or transient soft bounce. If it is a soft bounce, stop and do nothing. Only continue for hard bounces and spam complaints.

Step 3: Look up the contact in HubSpot using the Get Contact operation with the recipient email as the lookup property. If no contact is found, skip step 4 and still post a Slack alert noting that no CRM record was found.

Step 4: Call HubSpot Update Contact on the matched record. Set `hs_email_optout` to true and also set a custom property `email_status` to `invalid`. Append the bounce reason and the failure category to a notes-style property (for example `email_bounce_reason`) so the marketing team can see why the contact was deactivated.

Step 5: Send a Slack message via the Slack Bot integration's Send a Message operation to the `#marketing-ops` channel. The message should include: the affected email address, the failure category and a one-line plain-English diagnosis of the likely cause, a link or reference to the HubSpot contact if one was updated, the Customer.io delivery id and message id for traceability, and today's running bounce count so the team can see if there is a spike.

The agent's value is in interpreting the bounce reason text and deciding whether the contact should be deactivated (clearly dead mailbox, domain reject, or spam complaint) versus left alone (transient or ambiguous soft bounce). Be conservative: when in doubt, do not deactivate the contact, and flag it in Slack as needing human review.

Integrations to use: Customer.io as the webhook trigger source (no Customer.io action operations are called), HubSpot for Get Contact and Update Contact, and Slack Bot for Send a Message.

Additional information

What does this prompt do?
  • Listens for bounce and spam complaint events from Customer.io the moment they happen.
  • Skips soft bounces and only acts on real deliverability problems like dead mailboxes, blocked domains, and spam complaints.
  • Finds the matching contact in HubSpot and flags them as invalid so future campaigns stop emailing them.
  • Posts a short summary to your marketing-ops Slack channel with the affected contact, the likely cause, and the day's bounce volume so far.
What do I need to use this?
  • A Customer.io workspace where you can add a Reporting Webhook.
  • A HubSpot account you can connect, with permission to read and update contacts.
  • A Slack workspace and a channel where the bot can post bounce alerts.
How can I customize it?
  • Change which Slack channel the bounce alerts post to.
  • Adjust which HubSpot field gets updated (the built-in opt-out flag, a custom email status property, or both) and what value it gets set to.
  • Tune what counts as actionable: only hard bounces, only spam complaints, or both, and whether to ignore certain domains or test accounts.

Frequently asked questions

Will this also act on soft bounces?
No. Soft bounces are usually temporary (full mailbox, server timeout) and clear themselves up, so the workflow ignores them. Only hard bounces and spam complaints update HubSpot and trigger a Slack alert.
Does this delete contacts in HubSpot?
No. Contacts are kept in your CRM so you do not lose history. They are flagged as invalid (opted out, or with a custom status of your choice) so campaigns and sequences stop emailing them.
How do I change which Slack channel the alerts go to?
After you generate the workflow, open it and update the channel name in the Slack step. You can also send alerts to a private channel as long as the Slack bot is a member.
What if the bounced email does not match any HubSpot contact?
The workflow still posts the bounce to Slack with a note that no CRM record was found. That way you still see deliverability problems even for one-off sends or unmatched addresses.
Do I have to use HubSpot? Could this work with another CRM?
This starter is wired up for HubSpot. After generating it you can ask the agent to swap HubSpot for another CRM you have connected, such as Salesforce or Attio, and it will rewire the contact lookup and update steps.

Protect your sender reputation on autopilot.

Connect Customer.io, HubSpot, and Slack once. Every bounce gets cleaned from your CRM and surfaced to your team the moment it happens.