Send a weekly Slack report on HubSpot sequence performance using Make

high complexityCost: $10-29/mo

Prerequisites

Prerequisites
  • Make account (Core plan or higher recommended for the Code module)
  • HubSpot Sales Hub Professional or Enterprise (required for Sequences API access)
  • HubSpot connection configured in Make via OAuth
  • Slack connection configured in Make (Bot Token with chat:write scope)
Sequences API access

The HubSpot Sequences API is only available with Sales Hub Professional or Enterprise. Starter and free plans don't have API access to sequence data, even if sequences are available in the UI.

Why Make?

Make works well for sequence reporting if your team already uses it for other automations. The Iterator module handles per-sequence enrollment fetching, and the Code module calculates metrics. The trade-off is cost: each iteration counts as a Make credit, so the credit cost scales with the number of active sequences. With 10 sequences, expect ~15 credits per run (~60 credits/month). The Code module also requires the Core plan at $29/mo.

How it works

  • Scheduler triggers weekly on Monday morning
  • Set variable module computes the 7-day lookback timestamp in milliseconds
  • HTTP module fetches all sequences from HubSpot's CRM v3 objects API
  • Iterator module loops through each sequence
  • HTTP module (inside iterator) searches sequence_enrollments for each sequence
  • Code module aggregates enrollment data, calculates open/reply/meeting rates
  • Slack module posts the formatted report

Step 1: Create a scenario and schedule it

Create a new scenario in Make. Configure the schedule:

  • Schedule type: At regular intervals
  • Run scenario: Every week
  • Day: Monday
  • Time: 09:00
  • Timezone: Select your team's timezone

Step 2: Set date range variables

Add a Tools -> Set variable module:

  • Variable 1: seven_days_ago_ms = Unix milliseconds for 7 days ago
  • Variable 2: today_ms = Unix milliseconds for today midnight

Use Make's date functions: {{formatDate(addDays(now; -7); "X")}}000

Step 3: Fetch all sequences

Add an HTTP module (Make an API Call):

  • URL: https://api.hubapi.com/crm/v3/objects/sequences?limit=100
  • Method: GET
  • Headers: Use the HubSpot connection

This returns all sequences with their IDs and names.

Step 4: Iterate and fetch enrollments per sequence

Add an Iterator module to process each sequence individually. Then add an HTTP module inside the iterator:

  • URL: https://api.hubapi.com/crm/v3/objects/sequence_enrollments/search
  • Method: POST
  • Body type: Raw JSON
{
  "filterGroups": [
    {
      "filters": [
        {
          "propertyName": "hs_sequence_id",
          "operator": "EQ",
          "value": "{{sequence_id}}"
        },
        {
          "propertyName": "hs_enrollment_start_date",
          "operator": "GTE",
          "value": "{{seven_days_ago_ms}}"
        }
      ]
    }
  ],
  "properties": [
    "hs_sequence_id", "hs_enrollment_state",
    "hs_was_email_opened", "hs_was_email_replied",
    "hs_was_meeting_booked"
  ],
  "limit": 100
}
Operation cost with iterators

Each iteration through the HTTP module counts as 1 Make credit. With 10 sequences, this step alone costs 10 credits per run. Add a Sleep module (1 second) inside the iterator to respect HubSpot's 5 req/sec rate limit on the Search API.

Step 5: Aggregate results with a Code module

After the iterator, add a Code module to calculate metrics per sequence:

const sequences = JSON.parse(getVariable('sequences_response')).results || [];
const enrollmentBatches = JSON.parse(getVariable('all_enrollments'));
 
const seqMap = {};
for (const seq of sequences) {
  seqMap[seq.id] = seq.properties?.hs_sequence_name || `Sequence ${seq.id}`;
}
 
const metrics = {};
for (const batch of enrollmentBatches) {
  for (const e of batch.results || []) {
    const seqId = e.properties.hs_sequence_id;
    if (!metrics[seqId]) {
      metrics[seqId] = { name: seqMap[seqId] || seqId, enrolled: 0, opened: 0, replied: 0, meetings: 0 };
    }
    metrics[seqId].enrolled++;
    if (e.properties.hs_was_email_opened === 'true') metrics[seqId].opened++;
    if (e.properties.hs_was_email_replied === 'true') metrics[seqId].replied++;
    if (e.properties.hs_was_meeting_booked === 'true') metrics[seqId].meetings++;
  }
}
 
const report = Object.values(metrics)
  .filter(m => m.enrolled > 0)
  .sort((a, b) => b.enrolled - a.enrolled)
  .map(m => {
    const openRate = (m.opened / m.enrolled * 100).toFixed(1);
    const replyRate = (m.replied / m.enrolled * 100).toFixed(1);
    const meetingRate = (m.meetings / m.enrolled * 100).toFixed(1);
    return `*${m.name}* (${m.enrolled} enrolled)\n    Open: ${openRate}% | Reply: ${replyRate}% | Meeting: ${meetingRate}%`;
  });
 
return {
  breakdown: report.join('\n\n'),
  totalEnrolled: Object.values(metrics).reduce((s, m) => s + m.enrolled, 0),
  totalReplied: Object.values(metrics).reduce((s, m) => s + m.replied, 0),
  totalMeetings: Object.values(metrics).reduce((s, m) => s + m.meetings, 0),
};

If you're on the Free plan without the Code module, this workflow is difficult to build using only visual aggregators — the per-sequence percentage calculations require code.

Step 6: Send to Slack

Add a Slack module -> Create a Message:

  • Channel: #sales-reports
  • Text:
📧 *Weekly Sequence Performance Report*
 
*Total Enrolled:* {{totalEnrolled}}
*Total Replies:* {{totalReplied}}
*Meetings Booked:* {{totalMeetings}}
 
*Per-Sequence Breakdown:*
{{breakdown}}
 
_Last 7 days | Generated {{formatDate(now; "dddd, MMMM D, YYYY")}}_

For Block Kit formatting, use Slack -> Make an API Call with /chat.postMessage and a JSON body containing blocks.

Step 7: Test and activate

  1. Click Run once to test
  2. Inspect each module's output — verify enrollment counts match your HubSpot sequence dashboard
  3. Toggle the scenario to Active

Troubleshooting

Common questions

How many Make credits does this use per month?

Each run uses approximately 3 + N credits, where N is the number of active sequences (1 trigger + 1 variable + 1 sequences fetch + N enrollment searches + 1 code + 1 Slack). With 10 sequences, that's ~15 credits per run, ~60 credits/month — well within the Core plan's 10,000 credits.

Can I build this without the Code module?

Not practically. Calculating percentages per sequence from enrollment data requires code. The Iterator + Array Aggregator approach would need one aggregator per metric per sequence, which is unmanageable for more than 2-3 sequences.

What happens when new sequences are added in HubSpot?

The workflow fetches all sequences dynamically from the CRM v3 objects API, so new sequences appear automatically in the next run. No manual configuration needed.

Cost and credits

  • Core plan: $29/month for 10,000 credits (required for the Code module). This scenario uses approximately 3 + N credits per run, where N is the number of active sequences (1 trigger + 1 variable + 1 sequences fetch + N enrollment searches + 1 code + 1 Slack). With 10 sequences, that's ~15 credits per run, ~60 credits/month.
  • Free plan: Not practical — the Code module is required for percentage calculations, and the iterator will consume credits quickly.

Next steps

  • Use Make's Data Store to persist weekly metrics and add trend comparisons
  • Add a Filter after the Code module to only report sequences with more than 10 enrollments (skip low-volume test sequences)
  • Alert routing — use a Router to send underperforming sequences (reply rate below 3%) to a separate #sequence-alerts channel

Looking to scale your AI operations?

We build and optimize automation systems for mid-market businesses. Let's discuss the right approach for your team.