Notify Slack when a HubSpot deal over $50K is created using code

medium complexityCost: $0

Why code?

The code approach gives you two things no other option does: real-time delivery and zero ongoing cost. HubSpot's webhook API pushes deal.creation events to your server within seconds — no polling delay, no per-task fees. You pay only for hosting, which can be free on Vercel's serverless tier or about $5/mo on Railway.

The trade-off is setup complexity. You need to register a webhook subscription, deploy an endpoint, and handle the amount threshold check in code. If your team has a developer comfortable with Express or Flask, this takes 20-30 minutes. If not, Zapier or Make will get you to the same result faster.

How it works

  • HubSpot webhook subscription registers your endpoint to receive deal.creation events in near real-time
  • Webhook handler receives the event, fetches the full deal record via the CRM API, and checks the amount against your threshold
  • Slack Web API posts a Block Kit message with deal details and a direct link to the HubSpot record
  • Polling alternative — if you can't host webhooks, a cron job checks for recently created deals every 5 minutes

Prerequisites

Prerequisites
  • Node.js or Python
  • HubSpot private app token
  • Slack Bot Token
  • Server for webhook or cron for polling
Webhook vs polling

Webhooks give you real-time alerts the moment a deal is created, but require a publicly accessible endpoint. Polling with a cron job is simpler to deploy (no public server needed) but introduces a delay equal to your polling interval.

Step 1: Set up the webhook handler

Subscribe to deal.creation events via HubSpot webhooks, then create a handler that receives the event payload:

from flask import Flask, request, jsonify
from slack_sdk import WebClient
import requests, os
 
app = Flask(__name__)
slack = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
HEADERS = {"Authorization": f"Bearer {os.environ['HUBSPOT_ACCESS_TOKEN']}"}
THRESHOLD = 50000
 
@app.route("/webhook", methods=["POST"])
def handle():
    for event in request.json:
        deal_id = event["objectId"]
        deal = requests.get(
            f"https://api.hubapi.com/crm/v3/objects/deals/{deal_id}",
            headers=HEADERS,
            params={"properties": "dealname,amount"}
        ).json()
 
        amount = float(deal["properties"].get("amount") or 0)
        if amount < THRESHOLD:
            continue
 
        slack.chat_postMessage(
            channel=os.environ["SLACK_CHANNEL_ID"],
            text=f"New large deal: {deal['properties']['dealname']}",
            blocks=[
                {"type": "section", "text": {"type": "mrkdwn",
                    "text": f"*New Large Deal*\n*{deal['properties']['dealname']}*\nAmount: ${amount:,.0f}"}},
                {"type": "context", "elements": [{"type": "mrkdwn",
                    "text": f"<https://app.hubspot.com/contacts/YOUR_PORTAL_ID/deal/{deal_id}|View in HubSpot>"}]}
            ]
        )
    return jsonify({"ok": True})

Step 2: Filter deals by amount

The handler fetches the full deal record from HubSpot using the objectId from the webhook event, then checks the amount property against the $50,000 threshold. Deals below the threshold are skipped silently — no Slack message is sent.

You can adjust THRESHOLD to match your team's definition of a "large" deal.

Step 3: Post to Slack with Block Kit

The Slack message uses Block Kit formatting to display the deal name, amount, and a link back to HubSpot. The text field serves as the fallback for notifications and accessibility, while the blocks array controls the rich display in Slack.

Replace YOUR_PORTAL_ID in the HubSpot URL with your actual portal ID, which you can find in HubSpot under Settings > Account Defaults.

Step 4: Deploy and test

For webhooks:

  1. Deploy your handler to a server with a public URL (e.g., Railway, Render, or a VPS)
  2. In HubSpot, go to Settings > Integrations > Private Apps > your app > Webhooks
  3. Subscribe to the deal.creation event and point it to your /webhook endpoint
  4. Create a test deal in HubSpot with an amount over $50,000
  5. Verify the Slack message appears in your target channel within a few seconds

For polling (no public server needed):

If you can't host webhooks, poll every 5 minutes for deals created in the last 5 minutes with amount > 50000:

# crontab
*/5 * * * * python check_large_deals.py

Troubleshooting

Common questions

How do I verify that webhook events are actually from HubSpot?

HubSpot signs webhook payloads with your app's client secret via the X-HubSpot-Signature-v3 header. In production, always verify this signature before processing events. Without verification, anyone who discovers your endpoint URL could send fake deal creation events.

What if the deal amount is empty at creation time?

Some teams create deals without an amount and fill it in later. The webhook handler treats missing amounts as $0, so these deals are silently ignored. If you want to catch deals that are later updated to exceed the threshold, add a second webhook subscription for deal.propertyChange on the amount property.

Can I deploy this on Vercel or AWS Lambda?

Yes. The webhook handler works well as a serverless function. HubSpot retries failed deliveries for up to 24 hours, so cold start delays are handled automatically.

Cost

  • Free — hosting only.

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.