Route bounced Kit customer emails into HubSpot review

A Kit hard bounce creates a review task for a matching HubSpot customer, so the account owner can verify the address and choose an appropriate alternate contact route.

Automate.ax team6 min read

Integrations used in this example

Put possible customer contact gaps on a person's task list

Kit's hard-bounce event supplies the subscriber address. The automation searches HubSpot by email and checks the matching contact's lifecycle stage. If exactly one contact is marked as a customer, it creates a HubSpot task attached to that contact for the customer success owner.

The task asks the owner to verify the address and choose an appropriate alternate contact method. The workflow neither emails the bounced address nor resubscribes it. A hard bounce is a reason to investigate, not proof that the customer supplied a bad address.

One user reported unexpected bounces, including mail sent to their own address.Source: A Kit user's unexplained bounces on Reddit

What you'll tell the agent

  • The HubSpot customer success owner who should review matched customers.
  • The HubSpot task-to-contact association type and customer lifecycle value.
  • Account authorization, including a Kit V4 API key.

The agent will create the project and ask you for these details. When Automate.ax asks you to connect an account, authorize the integrations you want this workflow to use.

The agent can create the project and find your HubSpot owner and association type. This example uses a Kit V4 API key connection; the agent will guide you through account authorization.

The automation

The Kit hard-bounce trigger searches HubSpot for a single customer contact and creates an associated review task. Unmatched and noncustomer subscribers do not create tasks.

kit-customer-bounce-review.automation.ts
import { automation, t } from "automate.ax"
import { hubspot } from "automate.ax/hubspot"
import { kit } from "automate.ax/kit"

export default automation(
  "Review bounced Kit email addresses for customers",
  {
    parameters: [
      {
        label: "Customer success HubSpot owner ID",
        name: "successOwnerId",
        type: "text",
      },
      {
        label: "HubSpot task-to-contact association type ID",
        name: "taskContactAssociationTypeId",
        type: "number",
      },
      {
        label: "HubSpot customer lifecycle value",
        name: "customerLifecycleValue",
        type: "text",
        defaultValue: "customer",
      },
    ],
  },
  ({ parameters }) => {
    const bounce = kit.onSubscriberBounced()
    const search = hubspot.searchContacts({
      filterGroups: [
        {
          filters: [
            {
              propertyName: "email",
              operator: "EQ",
              value: bounce.data.subscriber.emailAddress,
            },
          ],
        },
      ],
      properties: ["email", "lifecyclestage"],
      limit: 2,
    })
    const match = search.transform(bounce, (page, event) => ({
      subscriberId: event.data.subscriber.id,
      email: event.data.subscriber.emailAddress,
      bouncedAt: event.created,
      contacts: page.records,
      hasMore: page.pageInfo.after !== undefined,
    }))
    const customer = match.filter(
      ({ contacts, hasMore }) =>
        contacts.length === 1 &&
        !hasMore &&
        contacts[0]?.properties.find(
          (property) => property.name === "lifecyclestage",
        )?.value === parameters.customerLifecycleValue,
    )
    hubspot.createTask({
      timestamp: customer.bouncedAt.transform((value) => new Date(value)),
      ownerId: parameters.successOwnerId,
      subject: t`Check an alternate contact route for ${customer.email}`,
      body: t`Kit reported a hard bounce for subscriber ${customer.subscriberId} at ${customer.bouncedAt}. Verify the address and customer record, then choose an appropriate alternate contact method. Do not email the bounced address or resubscribe it automatically.`,
      taskType: "TODO",
      associations: [
        {
          toRecordId: customer.contacts.transform(
            (contacts) => contacts[0]!.id,
          ),
          types: [
            {
              associationCategory: "HUBSPOT_DEFINED",
              associationTypeId: parameters.taskContactAssociationTypeId,
            },
          ],
        },
      ],
    })
  },
)

What a run looks like

Example input

Kit reports a hard bounce for pat@example.com, and HubSpot has one matching contact marked customer.

Expected result

Customer success gets a HubSpot task on Pat's contact record to verify the address and another appropriate contact route. No email is sent.

Set it up

  1. Copy the setup prompt at the top into your coding agent.
  2. Ask the agent to connect Kit using a V4 API key and authorize HubSpot. It can help find the customer success owner and task-to-contact association type.
  3. Check the actual HubSpot lifecycle value your portal uses for customers. The example defaults to customer.
  4. Deploy and use a disposable Kit test subscriber or safe webhook fixture to verify that only a unique matching customer gets a HubSpot task.

Check the result

Use a controlled Kit bounce event or test fixture. Confirm one HubSpot customer match creates an associated task, while an unmatched or noncustomer address does not. Check that no email or resubscription action ran.

Where this workflow stops

  • A bounce may have several causes. The task requests verification and does not label the address invalid.
  • Only a unique email match marked customer creates a task. Missing, duplicate, and noncustomer matches are skipped by this example.
  • The example does not check whether another email or phone number is available. The owner chooses an appropriate route after reviewing the contact.
  • A later, distinct bounce event for the same subscriber may create another task. Add subscriber-level deduplication if that occurs.

Common questions

Will it email the bounced address again?

No. It creates an internal HubSpot task and leaves contact decisions to customer success.

What if the subscriber is not a customer in HubSpot?

This example creates no task. Ask the agent to add a separate review path if other subscriber groups matter to your team.

More automation examples