> For the complete documentation index, see [llms.txt](https://developer.kizen.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.kizen.com/docs/concepts/objects/records/records-apis/create-or-update-records-upsert-api.md).

# Create or Update Records (Upsert) API

{% hint style="success" %}
**Audience:** Developers and Solution Architects

**Purpose:** Explains how to use the Create or Update <code class="expression">space.vars.entity</code> Upsert API to create or update <code class="expression">space.vars.entities</code> based on lookup identifiers while enforcing uniqueness, permissions, and archive conflict handling.
{% endhint %}

## Overview

Use the **Create or Update Records (Upsert)** endpoint to conditionally create a new <code class="expression">space.vars.entity</code> or update an existing one based on a lookup identifier. Lookup identifiers are governed by <code class="expression">space.vars.object</code>-level uniqueness rules and differ by <code class="expression">space.vars.entity</code> type.

This endpoint is designed for integration workflows that require duplicate prevention and dynamic create-or-update behavior.

The material on this page builds on information covered in [Records Core Concepts](/docs/concepts/objects/records/records-core-concepts.md) and the [Records Data Model](/docs/concepts/objects/records/records-data-model.md).

### Why Use This API?

Use the Upsert API when you need to create or update a <code class="expression">space.vars.entity</code> in a single request using a defined identifier.

Common scenarios include:

* Synchronizing data between external systems and the platform
* Preventing duplicate <code class="expression">space.vars.entities</code> during integration workflows
* Updating <code class="expression">space.vars.entities</code> when only a name or email is available
* Supporting incremental or bidirectional synchronization

Upsert achieves the same outcome as performing a Lookup followed by a Create or Update request, but combines matching and modification into a single API call.

Compared to separate lookup and write operations, Upsert:

* Reduces round trips between systems
* Simplifies integration logic
* Minimizes race conditions
* Supports reliable synchronization patterns

Upsert requires a clearly defined identifier strategy to ensure consistent matching behavior.

### **Create or Update Records (Upsert)** API Behavior

Use this endpoint to create or update a <code class="expression">space.vars.entity</code> by providing a lookup identifier. It:

* Evaluates the lookup identifier within the specified <code class="expression">space.vars.object</code>
* Creates a new <code class="expression">space.vars.entity</code> if no matching <code class="expression">space.vars.entity</code> exists
* Updates the existing <code class="expression">space.vars.entity</code> if a match is found
* Returns a response indicating whether a create or update action occurred
* Enforces <code class="expression">space.vars.object</code>-level uniqueness constraints
* Uses <code class="expression">space.vars.entity</code> name for most <code class="expression">space.vars.objects</code> and email for <code class="expression">space.vars.contact</code> <code class="expression">space.vars.entities</code>
* Applies validation rules and required field enforcement
* Respects permission constraints
* Applies archive conflict handling when a matching <code class="expression">space.vars.entity</code> exists in an archived state

***

## Unarchiving Using Entity Create or Upsert

When a lookup identifier matches a record that exists in an archived state, the Upsert endpoint may trigger archive collision behavior.

Depending on the archive conflict mode configured in the request:

* The archived record may be restored
* A new record may be created
* A conflict response may be returned

Archived conflict handling must be explicitly defined in the request. Upsert does not implicitly overwrite or restore archived records without intentional configuration. Developers implementing synchronization workflows should account for archived record scenarios to prevent unintended duplication or data resurrection.

***

## **Create or Update Records (Upsert)** Endpoint

Want to try the API out? Visit our [Swagger](https://app.go.kizen.com/api/docs/public/swagger#/records/records_upsert_create) docs.

## POST /api/records/{object\_identifier}/upsert

> Create or update entity record based on lookup criteria

```json
{"openapi":"3.0.3","info":{"title":"Kizen API","version":"1.0.0"},"security":[{"businessId":[],"userId":[],"apiKey":[]}],"components":{"securitySchemes":{"businessId":{"type":"apiKey","in":"header","name":"X-BUSINESS-ID"}},"schemas":{"EntityRecordUpsertRequest":{"type":"object","properties":{"lookup_value":{"type":"string","minLength":1,"description":"Value to match the entity record (name for custom objects, email for contacts)."},"oncreate_unarchive":{"nullable":true,"description":"Behavior when creating and a matching archived record exists.\n\n* `prompt` - prompt\n* `unarchive` - unarchive\n* `overwrite` - overwrite","oneOf":[{"$ref":"#/components/schemas/OncreateUnarchiveEnum"},{"$ref":"#/components/schemas/NullEnum"}]},"onupdate_archived_conflict":{"nullable":true,"description":"Updates the identifier of matching archived record to not raise a conflict during update.\n\n* `overwrite` - overwrite","oneOf":[{"$ref":"#/components/schemas/OnupdateArchivedConflictEnum"},{"$ref":"#/components/schemas/NullEnum"}]}},"required":["lookup_value"]},"OncreateUnarchiveEnum":{"enum":["prompt","unarchive","overwrite"],"type":"string","description":"* `prompt` - prompt\n* `unarchive` - unarchive\n* `overwrite` - overwrite"},"NullEnum":{"enum":[null]},"OnupdateArchivedConflictEnum":{"enum":["overwrite"],"type":"string","description":"* `overwrite` - overwrite"},"UpsertRecordResponse":{"type":"object","properties":{"object_type":{"type":"string"},"num_upcoming_activities":{"type":"integer"},"fields":{"$ref":"#/components/schemas/Fields"},"id":{"type":"string","format":"uuid"},"client_info":{"$ref":"#/components/schemas/ClientInfo"},"access":{"$ref":"#/components/schemas/AccessSerpy"},"num_associated_team_members":{"type":"integer"},"lead_source_types":{"type":"array","items":{"$ref":"#/components/schemas/LeadSourceType"}},"action":{"$ref":"#/components/schemas/ActionEnum"}},"required":["access","action","client_info","fields","id","lead_source_types","num_associated_team_members","num_upcoming_activities","object_type"]},"Fields":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/SerializedFieldValueDict"}},"required":["id"]},"SerializedFieldValueDict":{"type":"object","properties":{"id":{"type":"string"},"field_type":{"type":"string"},"display_name":{"type":"string"},"value":{"type":"object","additionalProperties":{}}},"required":["display_name","field_type","id","value"]},"ClientInfo":{"type":"object","properties":{"num_addresses_v2":{"type":"integer"},"display_name":{"type":"string"},"email_on_suppression_list":{"type":"boolean"}},"required":["display_name","email_on_suppression_list","num_addresses_v2"]},"AccessSerpy":{"type":"object","properties":{"view":{"type":"boolean"},"edit":{"type":"boolean"},"remove":{"type":"boolean"}},"required":["edit","remove","view"]},"LeadSourceType":{"type":"object","properties":{"value":{"$ref":"#/components/schemas/ValueEnum"},"label":{"type":"string"}},"required":["label","value"]},"ValueEnum":{"enum":["organic_search","direct_traffic","site_referral","facebook_ads","google_ads","social","paid_social","utm","custom"],"type":"string","description":"* `organic_search` - Organic Search\n* `direct_traffic` - Direct Traffic\n* `site_referral` - Site Referral\n* `facebook_ads` - Facebook Ads\n* `google_ads` - Google Ads\n* `social` - Social\n* `paid_social` - Paid Social\n* `utm` - UTM\n* `custom` - Custom"},"ActionEnum":{"enum":["created","updated","unarchived"],"type":"string","description":"* `created` - created\n* `updated` - updated\n* `unarchived` - unarchived"},"ErrorResponse":{"type":"object","properties":{"non_field_errors":{"type":"array","items":{"type":"string"}},"fields":{"type":"array","items":{"$ref":"#/components/schemas/_FieldError"}}},"required":["fields"]},"_FieldError":{"type":"object","description":"This is only used for rendering the error response schema.","properties":{"id":{"type":"array","items":{"type":"string"}},"name":{"type":"array","items":{"type":"string"}},"value":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}],"description":"Given the *incoming* primitive data, return the value for this field\nthat should be validated and transformed to a native value.","readOnly":true},"add_values":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}],"readOnly":true},"remove_values":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}],"readOnly":true}},"required":["add_values","remove_values","value"]}}},"paths":{"/api/records/{object_identifier}/upsert":{"post":{"operationId":"records_upsert_create","description":"Create or update entity record based on lookup criteria","parameters":[{"in":"path","name":"object_identifier","schema":{"type":"string"},"required":true},{"in":"query","name":"return_all_fields","schema":{"type":"boolean"},"description":"If true, return all fields even if not updated"}],"tags":["records"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityRecordUpsertRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertRecordResponse"}}},"description":""},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertRecordResponse"}}},"description":""},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":""}}}}}}
```

### **Create or Update Records (Upsert)** Schema

## The UpsertRecordResponse object

```json
{"openapi":"3.0.3","info":{"title":"Kizen API","version":"1.0.0"},"components":{"schemas":{"UpsertRecordResponse":{"type":"object","properties":{"object_type":{"type":"string"},"num_upcoming_activities":{"type":"integer"},"fields":{"$ref":"#/components/schemas/Fields"},"id":{"type":"string","format":"uuid"},"client_info":{"$ref":"#/components/schemas/ClientInfo"},"access":{"$ref":"#/components/schemas/AccessSerpy"},"num_associated_team_members":{"type":"integer"},"lead_source_types":{"type":"array","items":{"$ref":"#/components/schemas/LeadSourceType"}},"action":{"$ref":"#/components/schemas/ActionEnum"}},"required":["access","action","client_info","fields","id","lead_source_types","num_associated_team_members","num_upcoming_activities","object_type"]},"Fields":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/SerializedFieldValueDict"}},"required":["id"]},"SerializedFieldValueDict":{"type":"object","properties":{"id":{"type":"string"},"field_type":{"type":"string"},"display_name":{"type":"string"},"value":{"type":"object","additionalProperties":{}}},"required":["display_name","field_type","id","value"]},"ClientInfo":{"type":"object","properties":{"num_addresses_v2":{"type":"integer"},"display_name":{"type":"string"},"email_on_suppression_list":{"type":"boolean"}},"required":["display_name","email_on_suppression_list","num_addresses_v2"]},"AccessSerpy":{"type":"object","properties":{"view":{"type":"boolean"},"edit":{"type":"boolean"},"remove":{"type":"boolean"}},"required":["edit","remove","view"]},"LeadSourceType":{"type":"object","properties":{"value":{"$ref":"#/components/schemas/ValueEnum"},"label":{"type":"string"}},"required":["label","value"]},"ValueEnum":{"enum":["organic_search","direct_traffic","site_referral","facebook_ads","google_ads","social","paid_social","utm","custom"],"type":"string","description":"* `organic_search` - Organic Search\n* `direct_traffic` - Direct Traffic\n* `site_referral` - Site Referral\n* `facebook_ads` - Facebook Ads\n* `google_ads` - Google Ads\n* `social` - Social\n* `paid_social` - Paid Social\n* `utm` - UTM\n* `custom` - Custom"},"ActionEnum":{"enum":["created","updated","unarchived"],"type":"string","description":"* `created` - created\n* `updated` - updated\n* `unarchived` - unarchived"}}}}
```

## The EntityRecordUpsertRequest object

```json
{"openapi":"3.0.3","info":{"title":"Kizen API","version":"1.0.0"},"components":{"schemas":{"EntityRecordUpsertRequest":{"type":"object","properties":{"lookup_value":{"type":"string","minLength":1,"description":"Value to match the entity record (name for custom objects, email for contacts)."},"oncreate_unarchive":{"nullable":true,"description":"Behavior when creating and a matching archived record exists.\n\n* `prompt` - prompt\n* `unarchive` - unarchive\n* `overwrite` - overwrite","oneOf":[{"$ref":"#/components/schemas/OncreateUnarchiveEnum"},{"$ref":"#/components/schemas/NullEnum"}]},"onupdate_archived_conflict":{"nullable":true,"description":"Updates the identifier of matching archived record to not raise a conflict during update.\n\n* `overwrite` - overwrite","oneOf":[{"$ref":"#/components/schemas/OnupdateArchivedConflictEnum"},{"$ref":"#/components/schemas/NullEnum"}]}},"required":["lookup_value"]},"OncreateUnarchiveEnum":{"enum":["prompt","unarchive","overwrite"],"type":"string","description":"* `prompt` - prompt\n* `unarchive` - unarchive\n* `overwrite` - overwrite"},"NullEnum":{"enum":[null]},"OnupdateArchivedConflictEnum":{"enum":["overwrite"],"type":"string","description":"* `overwrite` - overwrite"}}}}
```

## The ErrorResponse object

```json
{"openapi":"3.0.3","info":{"title":"Kizen API","version":"1.0.0"},"components":{"schemas":{"ErrorResponse":{"type":"object","properties":{"non_field_errors":{"type":"array","items":{"type":"string"}},"fields":{"type":"array","items":{"$ref":"#/components/schemas/_FieldError"}}},"required":["fields"]},"_FieldError":{"type":"object","description":"This is only used for rendering the error response schema.","properties":{"id":{"type":"array","items":{"type":"string"}},"name":{"type":"array","items":{"type":"string"}},"value":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}],"description":"Given the *incoming* primitive data, return the value for this field\nthat should be validated and transformed to a native value.","readOnly":true},"add_values":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}],"readOnly":true},"remove_values":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}],"readOnly":true}},"required":["add_values","remove_values","value"]}}}}
```

***

## What’s Next

After implementing Create or Update <code class="expression">space.vars.entities</code> (Upsert) workflows, you can:

* Retrieve a <code class="expression">space.vars.entity</code> by name or email to confirm matching behavior
* Use ID-based endpoints to perform targeted updates or lifecycle actions
* Add new <code class="expression">space.vars.entities</code> explicitly when guaranteed creation is required
* Search <code class="expression">space.vars.entities</code> for multi-record filtering and validation
* Incorporate Upsert workflows into schema-aware integrations

For more information on <code class="expression">space.vars.entity</code> operations, see the related <code class="expression">space.vars.entities</code> API topics below:

<details>

<summary>Related Topics</summary>

* [Add Records API ](/docs/concepts/objects/records/records-apis/add-records-api.md)
* [Manage Records by ID API](/docs/concepts/objects/records/records-apis/manage-records-by-id-api.md)
* [Lookup Record API](/docs/concepts/objects/records/records-apis/lookup-record-api.md)&#x20;
* [Search Records API](/docs/concepts/objects/records/records-apis/search-records-api.md)

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developer.kizen.com/docs/concepts/objects/records/records-apis/create-or-update-records-upsert-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
