Log Postmark bounces to HubSpot and alert deal owners in Slack

When an email hard-bounces or gets flagged as spam, the bounce gets logged on the matching HubSpot contact, a 3-day task lands with the deal owner, and your CRM hygiene channel gets a one-line ping.

Agentic Task
PostmarkHubSpotSlackSalesOperationsNotifications & AlertsData SyncEmail Automation

Build me an agent workflow that turns Postmark email bounces into clean records inside HubSpot, so my sales team never loses a contact to a silent bounce.

Trigger: an incoming webhook from Postmark. I will configure the workflow's webhook URL as the Bounce and Spam Complaint webhook on the relevant Postmark message stream. Postmark will POST a JSON payload that includes Type, TypeCode, Email, Description, Details, Tag, BouncedAt, and MessageStream.

Step 1. Look at the bounce Type. Only continue for HardBounce and SpamComplaint. For SoftBounce, Transient, AutoResponder, Unsubscribe, or anything else, exit silently. The CRM hygiene channel should not get noisy with transient failures.

Step 2. Look up the HubSpot contact whose email matches the bounced Email using HubSpot Get Contact with idProperty=email. Request the firstname, lastname, email, and hubspot_owner_id properties. If no matching contact is found, exit silently.

Step 3. If the contact has an owner, call HubSpot Get Owner with that owner id so you have the owner's first name and email for the Slack message and task assignment.

Step 4. Translate the Postmark bounce into a one-line plain-English reason a salesperson can understand. Examples: a HardBounce whose Description mentions 'mailbox does not exist' or 'user unknown' becomes 'Mailbox does not exist'. A HardBounce with policy or block language becomes 'Blocked by recipient mail server'. A SpamComplaint becomes 'Recipient marked our email as spam'. If nothing else fits, fall back to the Postmark Description field verbatim.

Step 5. Use HubSpot Create Note to attach a note to the contact, associated via the contact-to-note association. The note body should include the bounce reason, the bounced address, the original Postmark Tag (so the salesperson knows which campaign or template caused it), the message stream, and the BouncedAt time in the team's local format.

Step 6. For HardBounce only, also call HubSpot Create Task to create a task associated with the contact and assigned to the contact's owner (hubspot_owner_id). Title it 'Update email address for {firstname} {lastname}'. Set the due date to 3 business days from now. Set priority to MEDIUM. Skip this task creation for SpamComplaint, because a complaint usually means the contact does not want to be emailed at all.

Step 7. Send one Slack message using Slack Send a Message to the channel #crm-hygiene. Keep it to a single line. For a hard bounce: 'Hard bounce for {Contact Name} (owner: {Owner First Name}): {bounce reason}.' For a spam complaint: 'Spam complaint from {Contact Name}, owner {Owner First Name}. Please review.' If there is no owner on the contact, omit the owner segment instead of writing 'unassigned'.

Keep the Slack message to a single line. No threads, no attachments, no @here, no Block Kit. Channel hygiene is the whole point of this workflow.

If any HubSpot call fails (rate limit, transient 5xx), retry once after a short backoff. If the Slack post fails, still consider the run successful as long as the HubSpot note was written, because the note is the source of truth and the Slack message is just a heads-up.

Additional information

What does this prompt do?
  • Catches every hard bounce or spam complaint the moment Postmark reports it, with no manual checking
  • Finds the matching HubSpot contact by email and attaches a plain-English note explaining what happened
  • Creates a 3-day follow-up task for the contact's owner to fix or replace the bad email address
  • Posts a single tidy line to your CRM hygiene Slack channel so the right person sees it without noise
What do I need to use this?
  • A Postmark account that sends your transactional or sales email
  • A HubSpot account where you can read contacts and create notes and tasks
  • A Slack workspace and a channel for CRM hygiene alerts, like #crm-hygiene
How can I customize it?
  • Change which Slack channel receives the alerts, or send a direct message to the owner instead
  • Adjust the task due date, priority, or skip the task entirely for certain email tags or campaigns
  • Add or remove which bounce types trigger the workflow if you also want to track soft bounces or unsubscribes

Frequently asked questions

Which bounce types does this watch for?
Hard bounces and spam complaints by default. Soft bounces, transient SMTP errors, auto-replies, and unsubscribes are ignored so your hygiene channel stays quiet.
What happens if the bounced email is not in HubSpot?
The workflow exits quietly. No note, no task, no Slack message. If the address was never a CRM contact, there is nothing to clean up.
Who gets the follow-up task to fix the email address?
Whichever HubSpot user is the contact's owner. If no owner is set, the task is created without an assignee so anyone on the team can pick it up.
Can I point multiple Postmark servers or message streams at this?
Yes. Point each server or stream's bounce webhook at the same workflow URL. The note and Slack message include the original message stream so you know which one fired.
Does this remove or unsuppress the bounced address?
No. Postmark handles suppression on its end. This workflow only records what happened inside HubSpot so a salesperson can decide whether to update the address or close the contact out.

Stop losing CRM contacts to silent email bounces.

Connect Postmark, HubSpot, and Slack once. Every hard bounce or spam complaint lands on the right contact, with the right owner notified.