Catch missing sales context when a HubSpot deal closes

Give customer success a Linear onboarding brief when a HubSpot deal closes, with sales promises and missing context to review before kickoff.

Automate.ax team7 min read

Integrations used in this example

Make the handoff visible before kickoff

When a HubSpot deal moves into the closed-won stage you choose, this example reads four deal properties: the customer's first 30-day outcome, promises made during sales, the customer champion, and known risks. It creates a Linear issue for the customer success team with those values, a link to the deal, and a list of missing fields.

The issue is created whether the brief is complete or not. A customer success owner can review it with sales before kickoff and assign the implementation work. Because the automation runs after the HubSpot stage change, it cannot block a rep from closing an incomplete deal.

The team said customer success often received only a name, contract value, and vague CRM use case; the first weeks of onboarding were spent discovering what sales had promised.Source: A customer success team's handoff account on Reddit

What you'll tell the agent

  • The HubSpot stage ID that means closed-won in your pipeline.
  • The four HubSpot deal property names for outcome, sales promises, champion, and risks.
  • The Linear team that reviews onboarding handoffs.
  • Account authorization.

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, help find or create the HubSpot properties, and identify the correct stage and Linear team after you connect the accounts.

The automation

The deal-stage event identifies the closed deal. The automation fetches the configured handoff properties and creates a Linear issue that names every empty field.

hubspot-closed-won-handoff-audit.automation.ts
import { automation, t } from "automate.ax"
import { hubspot } from "automate.ax/hubspot"
import { linear } from "automate.ax/linear"

export default automation(
  "Give customer success the context behind a won deal",
  {
    parameters: [
      {
        label: "Closed-won HubSpot stage ID",
        name: "closedWonStageId",
        type: "text",
      },
      {
        label: "30-day outcome property name",
        name: "outcomeProperty",
        type: "text",
      },
      {
        label: "Sales promises property name",
        name: "promisesProperty",
        type: "text",
      },
      {
        label: "Customer champion property name",
        name: "championProperty",
        type: "text",
      },
      {
        label: "Known risks property name",
        name: "risksProperty",
        type: "text",
      },
      {
        label: "Customer success Linear team ID",
        name: "successTeamId",
        type: "text",
      },
    ],
  },
  ({ parameters }) => {
    const won = hubspot
      .onDealUpdated()
      .filter(
        ({ propertyChanges }) =>
          propertyChanges.dealstage === parameters.closedWonStageId,
      )
    const deal = hubspot.getDeal({
      recordId: won.objectId,
      properties: [
        "dealname",
        parameters.outcomeProperty,
        parameters.promisesProperty,
        parameters.championProperty,
        parameters.risksProperty,
      ],
    })
    const brief = deal.transform(won, (record, event) => {
      const read = (name: string) =>
        record.properties
          .find((property) => property.name === name)
          ?.value?.trim() ?? ""
      const fields = [
        { label: "First 30-day outcome", property: parameters.outcomeProperty },
        {
          label: "Promises made in sales",
          property: parameters.promisesProperty,
        },
        { label: "Customer champion", property: parameters.championProperty },
        { label: "Known risks", property: parameters.risksProperty },
      ]
      const missing = fields
        .filter(({ property }) => !read(property))
        .map(({ label }) => label)

      return {
        dealName: read("dealname") || record.id,
        dealUrl: `https://app.hubspot.com/contacts/${event.portalId}/record/0-3/${record.id}`,
        outcome: read(parameters.outcomeProperty) || "Missing",
        promises: read(parameters.promisesProperty) || "Missing",
        champion: read(parameters.championProperty) || "Missing",
        risks: read(parameters.risksProperty) || "Missing",
        missing: missing.length ? missing.join(", ") : "None",
      }
    })

    linear.createIssue({
      teamId: parameters.successTeamId,
      title: t`Review onboarding handoff for ${brief.dealName}`,
      description: t`HubSpot deal: ${brief.dealUrl}\n\nFirst 30-day outcome: ${brief.outcome}\nPromises made in sales: ${brief.promises}\nCustomer champion: ${brief.champion}\nKnown risks: ${brief.risks}\n\nMissing handoff context: ${brief.missing}\n\nCustomer success should confirm these details with sales before kickoff.`,
      priority: 2,
    })
  },
)

What a run looks like

Example input

A deal becomes closed-won with an outcome and champion, but no written sales promises or risks.

Expected result

Customer success gets a Linear issue with the available details and an explicit missing-fields line naming sales promises and known risks.

Set it up

  1. Copy the setup prompt at the top into your coding agent.
  2. Agree on the four handoff questions with sales and customer success. Ask the agent to find or create corresponding writable HubSpot deal properties.
  3. Choose the closed-won stage and customer success Linear team, then authorize HubSpot and Linear.
  4. Have the agent deploy and move a disposable test deal into the stage. Review the Linear issue with both populated and blank handoff fields.

Check the result

Move a disposable HubSpot deal into the selected stage. Confirm the Linear issue links to the right deal, copies the four property values, and names blank fields. Repeat with a fully populated deal and confirm Missing handoff context reads None.

Where this workflow stops

  • The automation cannot require fields before a deal closes; it creates a review issue after the stage update. Use HubSpot's own stage rules if you need an actual close gate.
  • The Linear issue reflects values present when the deal was read. Later edits to the HubSpot brief do not update that issue.
  • A deal moved out of and back into the closed-won stage can create another issue. Add a durable handoff marker or deduplication if stage re-entry is common.
  • This captures written fields, not the quality or accuracy of the sales conversation. Customer success still confirms expectations with sales and the customer.

Common questions

Will this stop a rep from closing an incomplete deal?

No. It creates a visible Linear issue after the stage change. HubSpot stage requirements are the place to enforce a pre-close rule.

What if our portal uses different property names?

The agent asks for your property names and passes them as project parameters. It can also help create the fields if they do not exist.

More automation examples