Every dial clears one gate first: DNC list, the lead's local calling hours, attempt caps. Nothing routes around it.
One function decides. Auto-dial calls it, the click-to-call button calls it, and the REST API calls it. There is no second way to start a call.
Federal and internal DNC lists. Calling hours read from the lead's own timezone, daylight saving included. Attempt caps counted in the lead's local day. A placeholder Do Not Call registration number is refused exactly like a missing one. If the gate says no, the call never happens, and the reason is written on the record.
Answering-machine detection listens so the rep does not have to. A voicemail gets the message you recorded, from a library you keep per workspace, and the rep is already on the next lead.
A test key routes to a simulator that drives the same call state machine and the same gate as a live call. Reps run whole sessions, get blocked for real reasons, and learn the screen before you buy a single phone number.
Reps flip one toggle; owners set the pace per campaign. No single phone number takes more than 200 dials in a day, so volume spreads across the pool instead of burning one caller ID.
Call outcomes post to HubSpot on their own and contacts come back the other way. Everything else runs on signed webhooks and 69 documented API paths.
No feature gates and no per-minute meter. Every seat gets the whole product.
Reps never handle a password or an API key. Each rep gets one dialer link, it can only start that rep’s own session, and rotating it kills the old one.