https://www.loom.com/share/dc6f140be89b417f9a0e91c4b4b20ecf
Transform your HubSpot into a voice-first CRM. Search contacts, check deals, log notes, create tasks, and update your pipelineβall by voice, no laptop required.
- Overview
- Why This Ability?
- Prerequisites
- Setup Guide
- The 6 Modes
- Usage Examples
- Technical Architecture
- API Reference
- Troubleshooting
- File Structure
This OpenHome ability gives you voice control over your HubSpot CRM through 6 powerful modes:
- Search Contacts - Find contact details instantly
- Search Deals - Check deal status and values
- Log Note - Capture insights while they're fresh
- Create Task - Set reminders with natural dates
- Pipeline Summary - Get instant pipeline overview
- Move Deal Stage - Update deal stages by voice
Your CRM, at the speed of speech.
The LLM has zero access to your HubSpot account. It can't search contacts, look up deals, or log any activity. This ability bridges voice β HubSpot CRM API β your actual CRM data.
Without it: The LLM can only talk about sales concepts hypothetically.
With it: You can interact with your real pipeline, contacts, and deals by voice.
Perfect for:
- Sales reps between meetings
- Founders juggling multiple roles
- Account managers managing dozens of accounts
- Anyone who lives in HubSpot but isn't always at their desk
- HubSpot Account (Free or paid)
- Super Admin Access (required to create Private Apps)
- OpenHome installed with abilities enabled
- Go to your HubSpot account
- Click Settings βοΈ (top right)
- Navigate to Integrations β Private Apps
- Click "Create a private app"
Basic Info:
- App name:
OpenHome Voice Assistant - Description:
Voice-powered CRM assistant for OpenHome
Scopes Tab - Enable these permissions:
β Contacts:
crm.objects.contacts.read- Read contactscrm.objects.contacts.write- Create/update contacts
β Companies:
crm.objects.companies.read- Read companies
β Deals:
crm.objects.deals.read- Read dealscrm.objects.deals.write- Create/update dealscrm.schemas.deals.read- Read deal pipelines/stages
β Owners:
crm.objects.owners.read- Read users/owners
β Engagements:
sales-email-read- Read notes and tasks
- Click "Create app"
- Review permissions β "Continue creating"
- Click "Show token"
- Copy the token (format:
pat-na2-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) β οΈ Save it immediately - you won't see it again!
-
Copy these files to your OpenHome abilities folder:
main.py__init__.pyREADME.md
-
Set the ability's unique name and trigger words in the OpenHome dashboard.
-
Open
main.pyand replace the placeholder token on line 20:API_TOKEN: ClassVar[str] = "YOUR_TOKEN_HERE"
With your actual token:
API_TOKEN: ClassVar[str] = "pat-na2-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
-
Restart OpenHome
Test the connection:
# PowerShell
Invoke-RestMethod -Uri "https://api.hubapi.com/account-info/v3/details" `
-Headers @{"Authorization"="Bearer YOUR_TOKEN_HERE"}Expected Response:
{
"portalId": 12345678,
"timeZone": "US/Eastern",
"currency": "USD"
}β If you see this, you're ready to go!
What it does:
- Searches HubSpot contacts by name or email
- Speaks back: name, company, email, phone, lifecycle stage
- Caches result for follow-up commands
Voice Triggers:
- "Look up Sarah Chen"
- "Find the contact at Acme"
- "Who is john@acme.com"
- "Search for Ali"
Example:
User: "Look up Sarah Chen"
App: "I found Sarah Chen. She's at Acme Corp, email sarah@acme.com,
phone 555-1234. She's currently a qualified lead."
Features:
- β Smart filtering (single name, full name, email)
- β Handles multiple results ("I found 3 contacts...")
- β Lifecycle stage formatting (machine β human readable)
What it does:
- Searches deals by name
- Fetches pipeline stage names (auto-caches for 30 min)
- Speaks back: deal name, stage, amount, close date, owner
Voice Triggers:
- "How's the Acme deal?"
- "What's the status of Project Phoenix?"
- "Check the Widget Co deal"
Example:
User: "How's the Acme deal?"
App: "The Acme Corp deal is in Contract Sent. It's worth fifteen thousand
dollars. Close date: March 15th. It's owned by Jake."
Features:
- β
Stage ID β Label mapping (e.g.,
contractsentβ "Contract Sent") - β Currency formatting ($15,000 β "fifteen thousand dollars")
- β Date formatting (2026-03-15 β "March 15th")
- β Owner resolution (ID β first name)
What it does:
- Creates a note in HubSpot
- Associates with contact or company
- No confirmation needed (speed is the point!)
Voice Triggers:
- "Log a note on Acme: they want to move forward"
- "Add a note to Sarah Chen: interested in enterprise plan"
- "Note for TechCorp: follow up about pricing"
Example:
User: "Log a note on Acme: they want to move forward with the enterprise plan"
App: "Done. I've logged a note on Acme Corp: they want to move forward
with the enterprise plan"
Features:
- β LLM parsing (extracts target + content)
- β Smart target search (tries contact, then company)
- β Instant logging (appears in HubSpot timeline immediately)
What it does:
- Creates a task in HubSpot
- Parses natural language dates
- Associates with contact, company, or deal
Voice Triggers:
- "Create a task: send proposal to Acme by Friday"
- "Remind me to follow up with Sarah next Monday"
- "Task for Widget Co: schedule a demo, high priority"
Example:
User: "Create a task: send proposal to Acme by Friday"
App: "Done. I've created a task: send proposal to Acme, due Friday,
medium priority, associated with Acme."
Date Parsing:
| User Says | Parsed To | Time |
|---|---|---|
| "tomorrow" | Tomorrow | 9:00 AM |
| "today" | Today | 5:00 PM |
| "Friday" | This/Next Friday | 5:00 PM |
| "next Monday" | Next Monday | 9:00 AM |
| (no date) | Tomorrow | 9:00 AM |
Priority Levels:
- HIGH - "high priority"
- MEDIUM - (default)
- LOW - "low priority"
What it does:
- Fetches all open deals
- Groups by pipeline stage
- Calculates totals per stage
- Speaks concise summary
Voice Triggers:
- "How's my pipeline?"
- "Give me a pipeline summary"
- "What deals do I have open?"
Example:
User: "How's my pipeline?"
App: "Here's your pipeline. You have 12 open deals worth 187 thousand dollars
total. 3 deals in Appointment Scheduled worth 45 thousand dollars.
4 deals in Qualified to Buy worth 62 thousand dollars..."
Features:
- β Pagination support (handles 100+ deals)
- β Sorts by deal count (most active stages first)
- β Speaks top 6 stages only (voice-friendly)
- β Null-safe (treats missing amounts as $0)
What it does:
- Updates deal pipeline stage
- Requires confirmation (destructive action)
- Supports fuzzy matching and aliases
Voice Triggers:
- "Move the Acme deal to contract sent"
- "Update Widget Co to closed won"
- "Mark Acme as closed lost"
Example:
User: "Move the Acme deal to closed won"
App: "I'll move the Acme deal from Contract Sent to Closed Won. Confirm?"
User: "Yes"
App: "Done. I've moved Acme to Closed Won."
Stage Aliases:
| User Says | Interpreted As |
|---|---|
| "won" or "one" | Closed Won |
| "lost" | Closed Lost |
| "contract" | Contract Sent |
| "presentation" or "demo" | Presentation Scheduled |
| "appointment" | Appointment Scheduled |
| "qualified" | Qualified to Buy |
Speech Recognition Fix:
- Handles "closed one" β "Closed Won" (common STT error)
User: "CRM"
App: "HubSpot Ready. What would you like to do?"
User: "Look up Sarah Chen"
App: "I found Sarah Chen. She's at Acme Corp, email sarah@acme.com..."
App: "What would you like to do?"
User: "Log a note on her: interested in demo"
App: "Done. I've logged a note on Sarah Chen: interested in demo"
App: "What would you like to do?"
User: "Create a task: send demo link by tomorrow"
App: "Done. I've created a task: send demo link, due tomorrow..."
App: "What would you like to do?"
User: "How's my pipeline?"
App: "Here's your pipeline. You have 8 open deals worth 250 thousand..."
App: "What would you like to do?"
User: "Done"
App: "Goodbye."
Morning Pipeline Check:
"CRM" β "How's my pipeline?" β "Done"
Pre-Meeting Prep:
"CRM" β "Look up Sarah Chen" β "Done"
Post-Meeting Follow-up:
"CRM" β "Log a note on Acme: they're ready to sign" β
"Create a task: send contract by Friday" β "Done"
Base URL: https://api.hubapi.com
Auth: Bearer token (Private App)
Rate Limits: 100 requests/10 seconds
1. Mode Detection
- Priority-based keyword matching
- Specific modes checked before generic ones
- Example: "move deal" checked before "deal"
2. LLM Integration
- Uses
text_to_text_response()for parsing - Extracts structured data from natural language
- Examples: contact names, deal names, task details
3. Caching System
- Pipelines: 30-minute TTL
- Owners: 30-minute TTL
- Recent Results: Session-based (for follow-up)
4. Data Flow
Voice Input β STT β Mode Detection β Route to Handler
β
API Call to HubSpot
β
Process Response
β
Format for Voice
β
TTS β Voice Output
hubspot_ability/
βββ main.py # Core capability (700+ lines)
βββ __init__.py # Package initialization
βββ README.md # This file
Trigger words and the ability's unique name are managed in the OpenHome dashboard.
Location: hubspot_crm_prefs.json (auto-created)
Structure:
{
"pipelines": [...],
"pipeline_cache_updated": "2026-02-26T14:00:00Z",
"owners": [...],
"owners_cache_updated": "2026-02-26T14:00:00Z",
"recent_results": {
"type": "contact",
"items": [...]
}
}| Endpoint | Method | Mode | Purpose |
|---|---|---|---|
/account-info/v3/details |
GET | Setup | Validate token |
/crm/v3/objects/contacts/search |
POST | 1, 3, 4 | Search contacts |
/crm/v3/objects/companies/search |
POST | 3, 4 | Search companies |
/crm/v3/objects/deals/search |
POST | 2, 5, 6 | Search deals |
/crm/v3/pipelines/deals |
GET | 2, 5, 6 | Get pipeline stages |
/crm/v3/owners |
GET | 2 | Get team members |
/crm/v3/objects/notes |
POST | 3 | Create note |
/crm/v3/objects/tasks |
POST | 4 | Create task |
/crm/v3/objects/deals/{id} |
PATCH | 6 | Update deal stage |
Notes:
- Note β Contact:
202 - Note β Company:
190 - Note β Deal:
214
Tasks:
- Task β Contact:
204 - Task β Company:
192 - Task β Deal:
216
| Operator | Use Case | Example |
|---|---|---|
EQ |
Exact match | Email search |
CONTAINS_TOKEN |
Word match | Name search |
NOT_IN |
Exclusion | Open deals (not won/lost) |
Cause: Invalid or revoked token
Fix:
- Go to HubSpot β Settings β Integrations β Private Apps
- Find your app
- Click "Rotate token" or create new app
- Update token in
main.pyline 20
Cause: Record doesn't exist in HubSpot
Fix:
- Go to HubSpot web UI
- Verify the contact/company/deal exists
- Check spelling matches exactly
- Try searching in HubSpot first
Cause: Word number parsing (already fixed in current version)
Fix: Update to latest main.py - supports word numbers
Cause: Old version of code
Fix: Use latest main.py with corrected detection order
Already Fixed: Code includes alias "one" β "closed won"
Cause: Cache older than 30 minutes
Fix: Automatic refresh - just wait or restart ability
- Go to HubSpot β Contacts or Companies
- Click the record (e.g., Acme)
- Scroll to Activity Timeline
- Look for notes with today's timestamp
- Go to HubSpot β Tasks
- Filter by "Not Started"
- Look for tasks with subject matching your voice input
- Go to HubSpot β Deals
- Click the deal
- Check current stage matches what you said
| Mode | Trigger | Example |
|---|---|---|
| 1 | "look up" | "Look up Sarah Chen" |
| 2 | "how's the [deal]" | "How's the Acme deal?" |
| 3 | "log note" | "Log a note on Acme: ..." |
| 4 | "create task" | "Create a task: send proposal by Friday" |
| 5 | "pipeline" | "How's my pipeline?" |
| 6 | "move" or "update" | "Move Acme to closed won" |
| Exit | "done" | "Done" |
- Say "CRM" to activate - Don't try commands without activating first
- Be specific with names - Use full names when possible
- Natural dates work - "tomorrow", "Friday", "next Monday"
- Confirmation is mandatory - Mode 6 always asks before updating
- Say "Done" to exit - Clean exit back to normal personality
- Check HubSpot to verify - Always verify critical updates in web UI
- β¨ Create contacts by voice
- β¨ Create deals by voice
- β¨ Log calls and meetings
- β¨ Custom property access
- β¨ Multi-pipeline support
- β¨ Batch operations
Built for: OpenHome Abilities Platform
API: HubSpot CRM API v3
Author: Your Team
Version: 1.0.0
Last Updated: February 2026
Issues? Check the troubleshooting section above.
Feature requests? Document them for V2 planning.
Questions? Review the mode examples and API reference.
π You're all set! Say "CRM" and start managing your pipeline by voice.