You opened HubSpot Workflows looking for "fire this internal API every night at 2am Eastern" and found a beautiful tool for the wrong job. HubSpot Workflows are state-driven: a deal moves stages, a contact submits a form, a property changes value, and the workflow reacts. They are not a general-purpose scheduler for arbitrary HTTP endpoints, and the closest thing (the Scheduled trigger) sits behind Operations Hub Pro+ on most accounts. Here is how to think about the gap, and how to keep HubSpot for what HubSpot is great at while letting an external cron handle the "trigger my own API on a clock" half of the job.
If you want the short version: leave your HubSpot Workflows alone for the CRM-state cases (deal stage moves, contact properties changing, form submissions). For everything that is "run my code on this schedule and push the result into HubSpot", expose a small backend endpoint, gate it with a HubSpot Private App access token, and point Crontap at it. Every 1 minute on Pro, per IANA timezone, failure alerts straight into Slack.
What HubSpot Workflows do (and don't)
HubSpot Workflows live inside the Workflows tool. The shape of a Workflow is:
- A trigger (an event in HubSpot's CRM data: a contact enrolls, a deal hits a stage, a property changes, a date-based property comes due, a form is submitted).
- Branching logic (if/then on properties, time-delay steps).
- Actions (send an email, create a task, update a property, call a webhook, run a custom code action).
Workflows are extremely good at "react to something happening inside HubSpot". They are not built around the idea of "fire on the wall clock, regardless of any HubSpot state". You can fake it (a date-based trigger on a property that you keep updating, a Scheduled trigger in higher Operations Hub plans), but the moment the use case is "every weekday at 8am, hit my internal API and let me decide what to do with the result", you are pushing Workflows uphill.
The HubSpot docs are honest about this. The Workflows documentation frames Workflows around CRM events, contact lists, and deal stages. The Scheduled trigger documentation is gated and limited compared to a general scheduler.
Scheduled trigger plan gating (Operations Hub Pro+)
The closest thing HubSpot has to a real scheduler is the Scheduled trigger. It lets you fire a workflow at a fixed time, day, or recurring interval. Two things are worth knowing:
- The Scheduled trigger is gated to higher tiers in most account configurations. The standard way customers reach it is on Operations Hub Pro or above (see HubSpot Operations Hub plans and pricing). Marketing Hub Starter accounts and many Sales Hub accounts do not see it without an Ops Hub upgrade.
- Even when you have it, the Scheduled trigger fires the workflow against a fixed enrollment list (contacts, companies, deals, tickets). It is not a generic "fire this HTTP request at 02:00 Eastern" trigger.
If your job is "run a custom code action against this list of records on a cadence, then move them through the workflow", Scheduled triggers do the right thing inside HubSpot. If your job is "trigger something I built on my own backend that may or may not eventually push back into HubSpot", you are paying for Operations Hub Pro to use a fraction of the feature.
Why "trigger my own API on a clock" needs an external scheduler
Here is the case that does not fit Workflows cleanly:
- You have an internal endpoint (
https://your-app.example.com/jobs/sync-deals) that knows how to assemble new deal records from your data warehouse, BigCommerce, NetSuite, or whatever your source of truth is. - You want to call that endpoint on a real wall clock (e.g. nightly at 02:00 America/New_York, in the merchant's actual timezone).
- The endpoint pushes the result into HubSpot via the HubSpot API at the end.
There is no clean Workflow-shaped tool for the first two steps. Workflows want a HubSpot trigger; Workflows fire actions inside HubSpot or against HubSpot-aware webhooks; Workflows do not own the wall clock for arbitrary backends. You can twist them into doing it (the Scheduled trigger in Ops Hub Pro+ plus a custom code action that calls your endpoint) but you have effectively used HubSpot as a cron service that costs hundreds of dollars a month.
The cleaner shape is to keep HubSpot for what HubSpot does, expose your own job endpoint, and use a real scheduler to fire it. That is the pattern below.
The Crontap setup (HubSpot Private App token)
The only tricky part of this pattern is auth: your job endpoint will eventually need to call the HubSpot API, and HubSpot expects a Private App access token. Here is the end-to-end flow.
Step 1: Create a HubSpot Private App and copy the access token
In HubSpot, go to Settings > Integrations > Private Apps. Create a new Private App and grant it the scopes your job actually needs (e.g. crm.objects.deals.write, crm.objects.contacts.read). Save the app and copy the access token; HubSpot only shows it once.
Store the token as an environment variable in your backend, e.g. HUBSPOT_PRIVATE_APP_TOKEN.
Step 2: Build the job endpoint
The endpoint is a thin wrapper around the work you want done on a cadence. Two rules:
- Refuse anonymous traffic. Read an
Authorizationheader and reject if it does not match yourCRON_SECRET. - Return 200 quickly. If the work is long, kick it off in the background (a queue, a worker process, a HubSpot custom workflow webhook action) and return immediately.
export async function POST(request: Request) {
const auth = request.headers.get("authorization");
if (auth !== `Bearer ${process.env.CRON_SECRET}`) {
return new Response("Unauthorized", { status: 401 });
}
await pushDealsToHubspot({
token: process.env.HUBSPOT_PRIVATE_APP_TOKEN,
});
return Response.json({ ok: true });
}
The endpoint above does two things: it gates anonymous traffic with a bearer token, and it calls into your pushDealsToHubspot function, which uses the HubSpot Private App token to authenticate against api.hubapi.com.
Step 3: Generate the cron secret and store it on both sides
Generate a long random string locally:
openssl rand -base64 32
Add it as CRON_SECRET to your backend environment. Crontap will use the same string when it fires the request.
Step 4: Point Crontap at the endpoint
Head to Crontap and create a new schedule.
- URL. Paste your endpoint URL:
https://your-app.example.com/jobs/sync-deals. - Method.
POST. - Headers. Add
Authorization: Bearer <your CRON_SECRET>. Crontap stores the value encrypted; you do not see it again after saving. - Cadence. Type plain English ("every weekday at 02:00") or paste a cron expression. Crontap previews the next 5 fires inline.
- Timezone. Pick the IANA zone the schedule actually runs in. HubSpot Scheduled triggers use the portal's default timezone; Crontap is per-schedule so each job can run in its own zone.
- Failure alerts. Add an integration: email / webhook (Slack / Discord / Telegram). If the deal-push fails, the alert lands the moment the endpoint returns a non-2xx.
Press Perform test to fire a real request before you trust the cadence. If your endpoint returns 200, you are done. If you see 401, the bearer is mismatched. If you see 5xx, the work itself failed and the alerting just proved itself.
Fix this in 60 seconds with Crontap. Free tier available. No credit card. Schedule your first job.
Worked example: a B2B e-commerce team and the four-platform sync
Take a B2B e-commerce team syncing BigCommerce, NetSuite, AfterShip and HubSpot on named local times. Their stack is a small PHP orchestrator running on apps.example.com; HubSpot is the CRM of record; BigCommerce is the storefront; NetSuite is the ERP; AfterShip is the tracking layer. The team's day runs on America/New_York wall-clock times and they want their syncs to land at named hours that match human ops shifts.
Their actual cadence:
- 07:00 America/New_York. "Picklist PDP NetSuite Sync". Pull yesterday's new SKUs from NetSuite, sync the pick-list product detail pages on BigCommerce.
- 11:00 America/New_York. Same NetSuite sync, second pass for late entries.
- 13:00 America/New_York. "Aftership Tracking Sync". Pull tracking updates from AfterShip, push the events into BigCommerce order timelines.
- 17:00 America/New_York. Same AfterShip sync, end-of-day pass.
- 22:00 America/New_York. "Create HubSpot Deals". Roll up the day's BigCommerce orders into HubSpot deal records, with the ERP cost attached.
Five jobs, five named local times, four platforms. None of these fit cleanly inside HubSpot Workflows because the trigger is the wall clock, not a HubSpot event. They also do not all live on HubSpot's side: the NetSuite and AfterShip syncs do not touch HubSpot at all, and the deal push is the last hop of a pipeline that started outside HubSpot.
Old shape (HubSpot Workflows + Operations Hub Pro for the schedule).
You would need Operations Hub Pro for the Scheduled trigger, and even then you would only get the deal-push step inside HubSpot. The other four jobs (NetSuite syncs, AfterShip syncs) still live elsewhere and need a different scheduler. So you end up paying for Ops Hub Pro to schedule one out of five jobs.
New shape (Crontap + Private App token).
Five Crontap schedules, all in America/New_York, each pointing at a different endpoint on apps.example.com. The deal-push endpoint internally uses the HubSpot Private App token to write deals via the HubSpot API. The team gets all five jobs in one dashboard, on named local times, with failure alerts that fire into the team's Slack the moment any of the five returns a non-2xx. HubSpot Operations Hub Pro is no longer required for the schedule itself; HubSpot is back to doing what HubSpot is good at (CRM, deals, reporting).
When HubSpot Workflows are still the right call
External cron is a shape, not a religion. There are cases where HubSpot Workflows are the right primitive and you should not reach for an external scheduler at all:
- CRM-state triggers. "When a deal moves to Closed Won, send an internal Slack message and create a follow-up task." This is exactly what Workflows are built for. An external scheduler cannot tell you a deal moved.
- Contact lifecycle automations. "When a contact submits the Pricing form, enroll them in the nurture sequence." Same shape.
- Date-based property triggers. "30 days after the renewal date, fire a check-in." Workflows handle date math against properties cleanly.
- HubSpot-internal data work. Anything where the source of truth is HubSpot and the action stays inside HubSpot is best done in Workflows. You are not buying a scheduler; you are buying state-aware automation.
The wedge is intent. If the trigger you want is "an event happened in HubSpot", use Workflows. If the trigger you want is "the wall clock said it is time to run my own code", use an external scheduler and let your code push into HubSpot via the Private App token at the end of its run.
FAQ
Do I still need Operations Hub Pro?
Only if you genuinely use the Pro features (datasets, AI breeze, scheduled enrollments inside HubSpot, programmable automation). If your only reason to upgrade was the Scheduled trigger, an external scheduler covers the cron half for $3.25/mo billed annually and lets you keep HubSpot on the tier that matches the rest of your usage.
Can I call the HubSpot API directly from Crontap and skip my backend?
You can, but it is fragile. You would store the HubSpot Private App token in Crontap's headers and POST directly against https://api.hubapi.com/.... That works for one-line jobs (toggle one property, fire one webhook) but most real jobs need to read a database, build a payload, and only then call HubSpot. The standard pattern is one thin endpoint on your backend that does that work and uses the Private App token internally.
What about HubSpot's webhooks API?
HubSpot's webhooks API goes the other direction: HubSpot calls you when something changes. That is event-driven, not scheduled. Crontap fires the schedule and your endpoint then calls into HubSpot via the API. Different problems, both useful.
Does this work for the HubSpot Forms API and Marketing emails?
Yes. The pattern is the same: your scheduled endpoint can submit to the Forms API or the Marketing Email API using the Private App token. Crontap fires the endpoint; the endpoint decides what to do with HubSpot.
Will Crontap and HubSpot Workflows conflict if I run both?
No. They run independently. Most teams keep HubSpot Workflows for everything CRM-state-driven and add Crontap for everything wall-clock-driven. Failure alerts, retries, and timezones live with the scheduler that is firing the work; Workflows logs live in HubSpot.
What cadence can I run on Crontap?
Every 1 minute on Pro at $3.25/mo billed annually. Free tier available with no credit card. There is no per-fire cost the way there is with Operations Hub workflow enrollments, so a 1-minute cadence does not change your bill.
References
- HubSpot Workflows knowledge base
- HubSpot Operations Hub plans and pricing
- HubSpot Private Apps documentation
Related on Crontap
- Cron jobs for HubSpot workflows. The HubSpot-specific guide to running scheduled work that pushes into HubSpot via Private App tokens, with the four-platform sync pattern in detail.
- Vercel Cron every minute: the Hobby hourly limit and how to beat it. The same external-cron shape applied to a different platform; useful if your HubSpot-pushing endpoint lives on Vercel.
- The Zapier Schedule task cost math. The cost-math angle on a peer SaaS automation tool, with the same wedge.
