Hourly HubSpot to Nooks: enrich phones and auto-enroll new ICP contacts

Every hour, send new ICP-matching HubSpot contacts to Nooks with Apollo-enriched phone numbers and drop them into the right outbound sequence by job title.

Agentic Task
HubSpotApolloNooksSalesOperationsLead EnrichmentData Sync

Build me an agent workflow that runs every hour on a cron trigger. The goal is to take newly created HubSpot contacts that match our ICP, enrich their phone numbers with Apollo, mirror them into Nooks, and enroll each one into the right outbound sequence based on job title.

Step 1. Pull new HubSpot contacts. Use HubSpot Search Contacts to find contacts where createdate is within the last hour. Apply a configurable ICP filter on top of that. Default the filter to lifecycle stage equals 'lead' OR 'marketingqualifiedlead', but expose lifecycle stage and lead source as inputs the user can override. Return at least these properties on each contact: firstname, lastname, email, phone, mobilephone, jobtitle, company, hs_lead_status, hs_calculated_phone_number, and hs_legal_basis (so we can detect Do Not Call).

Step 2. Filter out anyone marked Do Not Call in HubSpot before doing anything else. Also drop anyone missing an email address, since Nooks will reject them with UNPROCESSABLE_ENTITY.

Step 3. For any remaining contact that is missing both a mobile and a direct-dial phone number, call Apollo People Enrichment using the contact's email (and name + company as fallback identifiers for match accuracy). If Apollo returns a mobile or direct number that HubSpot does not already have, write it back to HubSpot using Update Contact. Never overwrite an existing phone value. Note Apollo enrichment consumes credits, so only call it for contacts that actually need a phone.

Step 4. Mirror the contacts into Nooks. Use Nooks Sync Prospects from CRM with integrationType 'hubspot' and the HubSpot contact IDs as external IDs. Batch up to 100 IDs per call. The response returns per-record results and errors. Log every entry in errors[] (NOT_FOUND_IN_CRM, MAPPING_FAILED, etc.) into the run summary so the user knows which contacts failed and why. Use the prospect IDs returned in results[] for the next step.

Step 5. Pick the right sequence per prospect using a simple title-to-sequence mapping the user supplies. Default mapping: titles containing 'VP', 'Chief', 'Head of', 'Director', or 'President' go to a sequence named 'Exec Outbound'. Everything else (IC and manager roles) goes to 'Practitioner Outbound'. Resolve those sequence names to Nooks sequence IDs by calling Nooks List Sequences once at the start of the run and caching the name to ID lookup. If the user-provided mapping references a sequence name that does not exist in Nooks, stop and report it instead of guessing.

Step 6. Before enrolling, dedupe. For each prospect, check Nooks List Sequence States filtered by that prospect ID to see if they are already enrolled in any active sequence. If they are, skip them and note it in the summary. This avoids the CONFLICT error Nooks returns on duplicate enrollment.

Step 7. Call Nooks Enroll Prospect in Sequence for each remaining prospect with its mapped sequence ID. If a 422 UNPROCESSABLE_ENTITY comes back (prospect missing valid email or marked Do Not Call inside Nooks), log it and continue. If a 409 CONFLICT comes back, treat it as already enrolled and continue. Never fail the whole run on a single bad prospect.

Step 8. Output a run summary with these counts: contacts pulled, contacts dropped for DNC or missing email, contacts enriched via Apollo (and how many phones were written back), prospects synced to Nooks (success vs error), prospects already enrolled (skipped), prospects newly enrolled per sequence, and a list of any per-record errors with the contact name, email, and reason. Keep the summary short and scannable.

Make the ICP filter, the title-to-sequence mapping, and the fallback behavior for unmatched titles (skip vs default sequence) all configurable inputs on the workflow. Default the trigger to every hour but let the user change the cadence.

Additional information

What does this prompt do?
  • Pulls newly created HubSpot contacts every hour and keeps only the ones that match your ICP filter (such as lifecycle stage or lead source).
  • Uses Apollo to fill in missing mobile and direct-dial phone numbers so reps actually have something to dial.
  • Mirrors each contact into Nooks as a prospect and enrolls them into the right outbound sequence based on a simple job-title mapping you provide.
  • Respects Do Not Call flags, skips anyone already enrolled, and reports any contacts that failed to sync so nothing falls through the cracks.
What do I need to use this?
  • A HubSpot account where new contacts are being created.
  • An Apollo account with credits available for people enrichment.
  • A Nooks workspace with outbound sequences already built (one for senior buyers, one for practitioners, or whatever mapping you prefer).
  • A list of job-title keywords you want to route to each sequence.
How can I customize it?
  • Change how often it runs. Hourly is a good default, but you can shorten the window for high-volume teams or lengthen it for slower pipelines.
  • Adjust the ICP filter. Swap lifecycle stage for lead source, country, persona, or any combination of HubSpot contact properties you care about.
  • Edit the title-to-sequence mapping. Add more buckets (founders, managers, IC roles by function) or point each bucket at a different Nooks sequence.

Frequently asked questions

Will it overwrite phone numbers that are already in HubSpot?
No. The agent only asks Apollo for a phone number when the contact does not already have one. Existing numbers in HubSpot are left alone.
What happens if a contact is already in a Nooks sequence?
Nooks rejects duplicate enrollments, and the agent treats that as a no-op instead of an error. The contact stays in their current sequence and the run keeps going.
Does this work with HubSpot Free?
Yes. The agent uses standard contact properties that exist on every HubSpot tier, including Free. Lifecycle stage and lead source are available everywhere.
What about Do Not Call contacts?
Those are filtered out before anything is sent to Nooks. Nooks itself also blocks enrollment for prospects marked Do Not Call, so there are two layers of protection.
What if a contact does not match any of my title buckets?
You can tell the agent to either skip those contacts or send them to a default fallback sequence. The default is to skip and include them in the run summary so you can review.

Stop hand-loading new leads into your dialer.

Connect HubSpot, Apollo, and Nooks once, and Geni keeps your outbound sequences full of fresh, phone-enriched ICP contacts every hour.