Ask For It, Or It Isn't There.
This video explains the HubSpot API skill for Claude plugins. All five record types share one path, but a plain call returns only a few default fields, and the search endpoint can miss a record created moments ago.
A common assumption is that calling HubSpot's contacts endpoint hands back everything about a contact. It does not; it returns only the fields you name. This video from the Claude Basics playlist covers the HubSpot API skill for Claude plugins and explains why asking for what you want is the central habit when working with HubSpot records.
One path for five record types
HubSpot's five record types, contacts, companies, deals, tickets and custom objects, all live under the same path, /crm/v3/objects/ followed by the object type. List, get, create, update, delete and search work identically for all five. Only the type name changes.
Properties are opt-in
The part that trips people up is that a plain get or list call returns only a small set of default fields: an internal ID, a couple of timestamps, and one or two type-specific fields such as email for a contact. Every other property is opt-in. You must name exactly the fields you want, or the record comes back looking almost empty. The field is not missing; you simply never asked for it.
Dedup rules differ by type
Each record type has its own rule for duplicates.
- Contacts dedupe on email. Creating one that already exists produces a conflict, not a copy.
- Companies dedupe on domain.
- Deals and tickets have no dedup key at all, so you have to check before you create one.
Typed associations and the property catalog
Links between records, such as a deal tied to a contact or a contact tied to a company, are typed associations. They are discovered and created through their own endpoint. Before writing anything, the video recommends reading the property catalog first, which lists the names and allowed values for every field, so a request does not fail on a name that was guessed wrong.
The catch: search lags
HubSpot's search endpoint is eventually consistent. Create or update a record and search for it immediately, and it might not show up yet, because the write and the search index are not on the same clock. The skill gives no guidance on how long to wait or when to give up, so a script that searches right after creating a record can silently miss it. A missing result does not mean the record is absent; the index may just not have caught up. When you need certainty, look the record up directly by its ID instead of trusting a search you just triggered.
Key takeaways
- All five HubSpot record types share one path, with only the type name changing.
- A plain get or list returns only a few default fields; every other property is opt-in.
- Name the exact properties you want, or records look nearly empty.
- Contacts dedupe on email and companies on domain; deals and tickets have no dedup key.
- Associations between records are typed and handled through their own endpoint.
- Read the property catalog before writing, to avoid guessing field names.
- Search is eventually consistent, so a just-created record may be missing; fetch by ID when you need to be sure.
Try it yourself
Paste this into Claude: use the HubSpot API skill to find all contacts in the lead lifecycle stage created in the last 30 days, and return their email and phone number. Then check what Claude does. Does it pass the properties for email and phone, or come back with near-empty records? Does it follow the pagination cursor through every page of results? And does it mention that a contact created moments ago might not show up in search yet? Run it on your own HubSpot workspace or a sandbox account.
Chapters
Full transcript(auto-generated, with timestamps)
The naive framing: "do I get back everything?"
[0:00]Someone assumed calling HubSpot's contacts endpoint would hand back everything about a contact. It won't, only the fields you name. So, does calling the endpoint return everything or only what I ask for?
One path, opt-in fields
[0:11]HubSpot's five record types, contacts, companies, deals, tickets, and custom objects all live under the same path. /crm/v3/objects/object type. List, get, create, update, delete, and search work identically for all five. Only the type name changes. But, here's the part that trips people up. A plain get or list call returns only of default fields, an internal ID, and a couple of timestamps. Plus one or two type-specific fields like email for a contact. Every other property is opt-in. You have to name exactly the fields you want, or the record comes back looking almost empty. Not because the field is missing, but because you never asked for it. Each record type has its own rule
Dedup keys, typed links
[0:50]For duplicates. Contacts did up on email. Create one that already exists, and you get a conflict, not a copy. Companies did up on domain. Deals and tickets have no did up key at all, so you have to check before you create one. Links between records, a deal tied to a contact, a contact tied to a company, or typed associations discovered and created through their own endpoint. Before writing anything, it pays to read the property catalog first. The names and allowed values for every field, so a request doesn't fail on a name you guessed wrong.
The catch: search lags
[1:19]Here's the catch. HubSpot's search endpoint is eventually consistent. Create or update a record, then immediately search for it, and it might not show up yet. The write and the search index aren't on the same clock. The skill never says how long to wait or when to give up, so a script that searches right after creating a record can silently miss it. A missing result doesn't mean the record isn't there. It might just mean the index hasn't caught up yet. If you need to be sure, look the record up directly by its ID instead of trusting a search you just triggered. A
Carry-out
[1:46]HubSpot record gives back only the properties you name, nothing else. And a search run right after you create that record can still come back empty because the index hasn't always caught up yet.
Your turn
[1:57]Your turn, paste this into Claude. Use the HubSpot API skill to find all contacts in the lead lifecycle stage created in the last 30 days and return their email and phone number. Then check what Claude does. Does it pass properties equals email, phone, or does it come back with near empty records? Does it follow the pagination cursor through every page of results or stop at the first one? And does it mention that contact created moments ago might not show up in search yet because the index takes a moment to catch up.
Outro
[2:25]Ask for it or it isn't there. Lay 'em in for bare.





