# Contact batch upsert endpoint

**URL:** <https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755>\
**Category:** APIs & Integrations\
**Tags:** contacts\
**Created:** [July 11, 2024, 7:22pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755 "2024-07-11T19:22:01Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![LCM4](https://avatars.discourse-cdn.com/v4/letter/l/e8c25b/32.png) [@LCM4](https://community.hubspot.com/u/LCM4)\
**Post date:** [July 11, 2024, 7:22pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/1 "2024-07-11T19:22:01Z")

</div>

Hi!

I’m trying to use the upsert endpoint

`https://api.hubapi.com/crm/v3/objects/contacts/batch/upsert`

to update existing contacts and create not existing ones, but cannot get it to work

I’m passing the following body (first input exist so should update, and the following two does not exist and should create them)

```lia-code-sample
{
 "inputs": [
 {
 "id": "35791753356",
 "properties": {
 "firstname": "Maria",
 "lastname": "Johnson"
 }
 },
 {
 "id": "doesnotexist",
 "properties": {
 "firstname": "John 1",
 "lastname": "Doe 1",
 "email": "test.test1@test.com"
 }
 },
 {
 "id": "doesnotexist2",
 "properties": {
 "firstname": "John 2",
 "lastname": "Doe 2",
 "email": "test.test2@test.com"
 }
 }
 ]
}

```

But I get the following response

```lia-code-sample
{
 "status": "error",
 "message": "Updates in a single batch must specify its unique property.",
 "correlationId": "d6594c05-a699-4014-a51d-6693c172f179",
 "category": "VALIDATION_ERROR"
}

```

What am I doing wrong? The [documentation](https://developers.hubspot.com/beta-docs/reference/api/crm/objects/contacts/v3) says that when providing a not existing id it will create the contact but it does not work

---

<div class="post-metadata">

**Author:** ![SteveHTM](https://d10pqhm3lwygmk.cloudfront.net/user_avatar/community.hubspot.com/stevehtm/32/22074_2.png) [@SteveHTM](https://community.hubspot.com/u/SteveHTM)\
**Post date:** [July 11, 2024, 8:11pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/2 "2024-07-11T20:11:36Z")

</div>

@LCM4 - my reading of the descrption here suggests thst you need to provide the idProperty selection along with the id value. Using an email address as the idProperty that would look like:

```lia-code-sample
"inputs": [
 {
 "idProperty": "email",
 "id": "joe@company.com",
 "properties": {
 "additionalProp1": "string",
 "additionalProp2": "string",
 "additionalProp3": "string"
 }
 }
]

```

But there is a rather strange warning that “email upserts are not supported” - which maybe practically limits what you can use the API for. Unless this format works of course:

```lia-code-sample
"inputs": [
 {
 "idProperty": "hs_object_id",
 "id": "", #null for new contact
 "properties": {
 "email": "joe@company.com",
 "additionalProp2": "string",
 "additionalProp3": "string"
 }
 }
]

```

Best of luck!

Steve

---

<div class="post-metadata">

**Author:** ![LCM4](https://avatars.discourse-cdn.com/v4/letter/l/e8c25b/32.png) [@LCM4](https://community.hubspot.com/u/LCM4)\
**Post date:** [July 11, 2024, 10:21pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/3 "2024-07-11T22:21:51Z")

</div>

It would return this

```lia-code-sample
{
 "status": "error",
 "message": "Duplicate IDs found in batch input: []. IDs must be unique",
 "correlationId": "218c3962-47cc-4248-87ea-0064604ff943",
 "context": {
 "ids": [
 ""
 ]
 },
 "category": "VALIDATION_ERROR"
}

```

> * * *
> 
> But there is a rather strange warning that “email upserts are not supported” - which maybe practically limits what you can use the API for.
> 
> * * *

Might be that since email is not supported here, or documentation is wrongly written on how pass the data correctly (seen that before). Tried the V1 API where a similar endpoint exist and works just right, but yeah, this one does not 😞

And a note hehe

I’ve tried deleting the id, idProperty, both at the same time, leave the id for the one that exist and none of those are working

---

<div class="post-metadata">

**Author:** ![SteveHTM](https://d10pqhm3lwygmk.cloudfront.net/user_avatar/community.hubspot.com/stevehtm/32/22074_2.png) [@SteveHTM](https://community.hubspot.com/u/SteveHTM)\
**Post date:** [July 11, 2024, 10:43pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/4 "2024-07-11T22:43:02Z")

</div>

And if you do try to use ‘email’ as the idProperty…

```lia-code-sample
HTTP 400

{
 "status": "error",
 "message": "Unable to perform update/upsert by non-unique 0-1 property email in portal ID XX3719",
 "correlationId": "fccd25a3-fb03-45ed-bf1d-982736c99cbe",
 "category": "VALIDATION_ERROR"
}

```

Scatching my head for how this might work…

---

<div class="post-metadata">

**Author:** ![Tuscher](https://avatars.discourse-cdn.com/v4/letter/t/eada6e/32.png) [@Tuscher](https://community.hubspot.com/u/Tuscher)\
**Post date:** [July 27, 2024, 8:32pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/5 "2024-07-27T20:32:20Z")

</div>

I have the same issue. Seems that the upsert endpoint is completely useless.

---

<div class="post-metadata">

**Author:** ![SAMsan](https://d10pqhm3lwygmk.cloudfront.net/user_avatar/community.hubspot.com/samsan/32/17908_2.png) [@SAMsan](https://community.hubspot.com/u/SAMsan)\
**Post date:** [August 27, 2024, 1:18pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/6 "2024-08-27T13:18:15Z")

</div>

So should we consider documentation is wrong and we can’t batch update/insert contacts?  
I tried to get this working according to guidelines without any success, it returns error 400 if using `email` as `idProperty` value  
Response is : `Unable to perform update/upsert by non-unique 0-1 property email in portal ID XXX`.

Batch read does work correctly with same params.

---

<div class="post-metadata">

**Author:** ![SteveHTM](https://d10pqhm3lwygmk.cloudfront.net/user_avatar/community.hubspot.com/stevehtm/32/22074_2.png) [@SteveHTM](https://community.hubspot.com/u/SteveHTM)\
**Post date:** [August 27, 2024, 1:57pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/7 "2024-08-27T13:57:36Z")

</div>

Yes - seems useless for most obvious practical purposes. Like many things its not clear how you can get this feedback to the product management team.

Steve

---

<div class="post-metadata">

**Author:** ![JMacias5](https://avatars.discourse-cdn.com/v4/letter/j/c37758/32.png) [@JMacias5](https://community.hubspot.com/u/JMacias5)\
**Post date:** [January 12, 2025, 11:46pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/8 "2025-01-12T23:46:18Z")

</div>

Any work arounds or fixes been found?

---

<div class="post-metadata">

**Author:** ![LCM4](https://avatars.discourse-cdn.com/v4/letter/l/e8c25b/32.png) [@LCM4](https://community.hubspot.com/u/LCM4)\
**Post date:** [January 13, 2025, 10:56pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/9 "2025-01-13T22:56:52Z")

</div>

Haven’t tested it recently, and I don’t remember how i fixed this issue

But a workaround that maybe you try is  
1. Check by id or email, etc if the contact exists

2. If it exists, use the update endpoint

3. If it does not exist, use the create endpoint

Using this workaround will use 2 requests, but for me it is necessary

---

<div class="post-metadata">

**Author:** ![SAMsan](https://d10pqhm3lwygmk.cloudfront.net/user_avatar/community.hubspot.com/samsan/32/17908_2.png) [@SAMsan](https://community.hubspot.com/u/SAMsan)\
**Post date:** [August 28, 2024, 9:24am UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/10 "2024-08-28T09:24:50Z")

</div>

As an update, this endpoint totally works with custom objects although I can’t get associations working, the batch update/insert is OK.

---

<div class="post-metadata">

**Author:** ![VStruyf](https://avatars.discourse-cdn.com/v4/letter/v/46a35a/32.png) [@VStruyf](https://community.hubspot.com/u/VStruyf)\
**Post date:** [November 28, 2024, 8:57am UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/11 "2024-11-28T08:57:50Z")

</div>

I have the same error. Did you find the solution?

---

<div class="post-metadata">

**Author:** ![dannio](https://d10pqhm3lwygmk.cloudfront.net/user_avatar/community.hubspot.com/dannio/32/95715_2.png) [@dannio](https://community.hubspot.com/u/dannio)\
**Post date:** [January 14, 2025, 7:32am UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/12 "2025-01-14T07:32:02Z")

</div>

It worked for me when I specify email as the id though. Here’s my request:

POST [https://api.hubapi.com/crm/v3/objects/contacts/batch/upsert](https://api.hubapi.com/crm/v3/objects/contacts/batch/upsert)

```lia-code-sample
{
 "inputs": [
 {
 "properties": {
 "phone": "1234"
 },
 "id": "test1@gmail.com",
 "idProperty": "email"
 },
 {
 "properties": {
 "phone": "12345"
 },
 "id": "test2@gmail.com",
 "idProperty": "email"
 },
 {
 "properties": {
 "phone": "123456"
 },
 "id": "test3@gmail.com",
 "idProperty": "email"
 },
 {
 "properties": {
 "phone": "23455"
 },
 "id": "doesnotexistyet@gmail.com",
 "idProperty": "email"
 }
 ]
}

```

All updated if exists, and the one that didn’t "[doesnotexistyet@gmail.com"](mailto:doesnotexistyet@gmail.com%22) inserted without any issues.

---

<div class="post-metadata">

**Author:** ![lstepany](https://d10pqhm3lwygmk.cloudfront.net/user_avatar/community.hubspot.com/lstepany/32/54675_2.png) [@lstepany](https://community.hubspot.com/u/lstepany)\
**Post date:** [January 21, 2025, 2:30pm UTC](https://community.hubspot.com/t/contact-batch-upsert-endpoint/111755/13 "2025-01-21T14:30:29Z")

</div>

I faced the same issue and after investigating a bit I found out that the hs\_object\_id is not set as unique id in property settings (although it is unique). Funny enough!

![](https://d2qpr2jzcazej7.cloudfront.net/original/3X/5/5/55aa43eb7a3997c78f933fbbf62d53888e9574e2.png)

So besically it is not possible to use hs\_object\_id for butch upsert endpoint. A workaround would be to create a nea property and make it unique after what to create a workflow which will copy the original IDs to the newly created unique property. Then use that prop in the req body 😄
