HubSpot API: Ask for Every Field, or You Get Almost None
HubSpot's five record types share one API path, but a plain get or list call returns only a few default fields. The video explains opt-in properties, per-type dedup rules, typed associations and why search can lag behind a write.
Someone assumes that calling HubSpot's contacts endpoint will hand back everything about a contact. It will not. The video explains that you get only the fields you name, plus a few defaults, and that a search run right after a write can miss the new record. It is part of the Claude Basics playlist and covers a Claude plugin skill for the HubSpot API.
One path for five record types
HubSpot's five record types are contacts, companies, deals, tickets and custom objects. All of them live under the same path, /crm/v3/objects/{objectType}. List, get, create, update, delete and search work identically for all five, and only the type name changes. That uniformity makes the API easy to learn, but it hides the detail that trips people up.
Properties are opt-in
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 have to 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. The video's one-line summary is that if you do not ask for it, it is not there.
Dedup rules and typed associations
Each record type has its own rule for duplicates:
- Contacts are deduplicated on email. Creating one that already exists gives a conflict, not a copy.
- Companies are deduplicated on domain.
- Deals and tickets have no dedup key at all, so you must check before you create one.
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 you guessed wrong.
Search is eventually consistent
The catch is that HubSpot's search endpoint is eventually consistent. If you create or update a record and then search for it immediately, it might not show up yet, because the write and the search index are not 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 therefore does not prove the record is absent. If you need to be sure, look the record up directly by its ID instead of trusting a search you just triggered.
What the video does not claim
The video makes no claim about how long the search index takes to catch up, since the source skill documents the behavior without giving wait or retry guidance and no number is invented. It also does not claim every object type behaves identically end to end. The uniform path and opt-in properties are shared across all five, but dedup keys and default fields differ per type.
Key takeaways
- All five HubSpot record types share the path /crm/v3/objects/{objectType}.
- A plain get or list returns only default fields, so near-empty records usually mean you did not name the properties.
- Contacts dedup on email, companies on domain, and deals and tickets have no dedup key.
- Associations between records are typed and discovered through their own endpoint.
- Read the property catalog before writing, so you use correct field names and allowed values.
- Search is eventually consistent, so a record created moments ago may not appear yet.
- When you must be certain a record exists, fetch it by ID.
Try it yourself
On your own HubSpot workspace or a sandbox account, 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 whether it names the email and phone properties, follows the pagination cursor through every page, and mentions that a just-created contact might not appear in search yet.
Chapters
Full transcript(auto-generated, with timestamps)
The naive framing: "do I get everything back?"
[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.
Dedup keys, typed links
[0:49]Each record type has its own rule 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 life cycle 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.
More from Claude
2:13Jira API: Claude Can't Set Status — It Has to Transition
3:10Can Claude Make a Good Chart? Only With a Charting Kit
2:29Linear Has No REST API — One GraphQL Endpoint, Two ID Systems
2:49Claude Meets an API It's Never Seen: The Grafana API Skill
2:25Notion API: The Data Source, Not the Database
1:46