I'm trying to hunt down a strange company sync issue connected to an API integration. Here's the sequence of events:
- A first company is created via some process other than our app's integration (via Hubspot web UI, user tracking, or something else)
- At signup time, our integration creates a second company record for the user, and supplies some app specific custom attributes. (Aside, I am aware that our app would benefit from an attempt to prevent duplication at this stage by performing a company lookup.)
- However, the integration records in our database have the Hubspot ID from first company, but also have the creation timestamp of the second company. My best guess at how this happens is that the Hubspot company create API response contains a different ID from the company that was actually created.
- As we store the Hubspot company ID for the first company, it continues to be updated by future sync events via our integration. The second company's integration attributes in the cases I've observed are out of date.
Is it possible that the Hubspot Companies API endpoint is attempting to do some deduplication, or is having confusion between the two records involved in this case? In all of the cases where I've seen this happen, the company names for the first and second companies are identical. From what I can tell, the companies have not been merged, but even if they were merged later I don't see how it could explain what's happening at creation time.
Hi @PatrickKing , that’s a weird one to debug, but your hypothesis (“the create response ID doesn’t match what was created”) is almost never what’s happening. HubSpot’s create endpoint should return the ID of the record it actually created when it returns a 201.
The more common pattern is: you think you created a second company, but HubSpot rejected the create as a duplicate, and your integration stored the existing company ID while your own “created_at” reflects when you attempted the create.
HubSpot’s company deduplication is primarily based on domain name, not company name. If you send the domain property and that domain already exists, you’ll typically get a 409 Conflict with an “Existing ID” rather than a new company being created (https://knowledge.hubspot.com/records/deduplication-of-records).
So if “company #1” was created earlier (UI, tracking, import) with the same domain, and your signup flow posts “company #2” with that domain, you can end up with exactly the mismatch you described unless your code explicitly handles 409 and switches into “update existing company” mode (https://developers.hubspot.com/docs/api-reference/crm-companies-v3/guide).
One quick clarifying question: in the calls where you observe this, are you setting the domain property on create, and what HTTP status are you logging back (201 vs 409)? If you’re not already, I’d log the full response body + status code and also the exact request payload. Then adjust the flow to: search by domain (or your own unique custom property if you have one) before create, and on 409 parse the existing ID and update that record instead of assuming a new one was created.
Did my answer help? Please mark it as a solution to help others find it too.
Ruben Burdin HubSpot Advisor Founder @ Stacksync Real-Time Data Sync between any CRM and Database
I can say that we are not providing the domain name, at the time that the integration was built we were not collecting a domain from our users.
And, I can also confirm that two records exist in Hubspot for the example cases I've seen. If there's a deduplication routine, it isn't suppressing the creation of the extra companies. The second/more recent records have custom attributes from our integration, and the record source shows as coming from our integration, but I can't find corresponding DB entries with those newer Hubspot company IDs.
Unfortunately, this happens rarely enough that I don't have any logs available. Checking our client code over, only 200 and 201 are considered successful, and the local record with the Hubspot company ID would only be created in that case. We have no special handling for a 409 response, we would just consider the attempt to make a company to have failed. Our app has "create or update" behaviour on sync, if it doesn't see a local DB record for a Hubspot company, it will try again to make one the next time a business logic event implies a sync.
I realize it would be very unusual for Hubspot's create company endpoint to be responding with an ID other than what it created, but I've been racking my brain for any other way this situation could come about. From what I can see in the docs, deduplication for company creation doesn't occur absent a domain name.