hubspot api 409 conflict contact already exists by email
Handles HubSpot's 409 when creating a contact whose email already exists: search first, then update instead of create. Use when the Contacts API returns 409 conflict on create with an existing email. Not for 400 validation errors or OAuth token failures.
TL;DR
HubSpot dedupes contacts by email, so a blind create conflicts. Search for the contact by email first, then PATCH the existing record; only create when the search comes back empty.
hubspot api 409 conflict contact already exists by emailUse this when
- POST to create a contact returns 409 conflict.
- An import job errors on duplicates mid-run.
- Upsert logic you wrote assumes create always works.
Not for this skill when
- 400 property validation errors.
- 401 expired OAuth tokens.
- Company or deal association errors, which have their own endpoints.
Steps
- Confirm the 409 body names the email as the conflicting identity. Verify: the error references the existing email address.
- Search contacts by email before creating. Verify: the search returns the existing contact with its ID.
- PATCH the existing contact with the new properties instead of creating. Verify: the response is 200 and the properties updated.
- Only POST a create when the search returns zero results. Verify: new emails create cleanly with 201.
- Make the job idempotent: wrap search-then-update in one function every caller uses. Verify: running the job twice produces no 409s and no duplicates.
Variant phrasings
hubspot contact already exists 409
Common phrasing of the conflict.
hubspot api create contact conflict email
The API-angle search.
hubspot upsert contact by email
The pattern-angle search.
Compatibility: HubSpot CRM v3 Contacts API; behavior applies to all portals.
Why it happens
Email is the unique identity for contacts in HubSpot. Two creates with the same email race into a conflict because the second one violates that uniqueness; HubSpot returns 409 rather than silently merging.
Edge cases / pitfalls
- The search API has its own rate limits; cache results inside a batch run.
- Associations are not carried over by a PATCH; set them separately.
- Custom dedupe rules on other identifiers do not apply to the email identity check.
- Deleted contacts can still conflict; check the recycle bin before assuming the email is free.
- The 409 response sometimes includes the existing contact ID; use it directly instead of a separate search.
- HubSpot dedupes email case-insensitively, so differently-cased versions of the same address still conflict.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_3m1d7wZjUukeNat4VfI5Bw