---
title: "Merge insert (upsert) records into a table"
method: POST
path: "/v1/table/{id}/merge_insert"
tags: ["Table", "Data"]
---

# Merge insert (upsert) records into a table

`POST /v1/table/{id}/merge_insert`

Performs a merge insert (upsert) operation on table `id`.
This operation updates existing rows
based on a matching column and inserts new rows that don't match.
It returns the number of rows inserted and updated.

REST NAMESPACE ONLY
REST namespace uses Arrow IPC stream as the request body.
It passes in the `MergeInsertIntoTableRequest` information in the following way:
- `id`: pass through path parameter of the same name
- `on`: pass through query parameter of the same name
- `when_matched_update_all`: pass through query parameter of the same name
- `when_matched_update_all_filt`: pass through query parameter of the same name
- `when_not_matched_insert_all`: pass through query parameter of the same name
- `when_not_matched_by_source_delete`: pass through query parameter of the same name
- `when_not_matched_by_source_delete_filt`: pass through query parameter of the same name

## Path parameters

- `id` string, required

## Query parameters

- `delimiter` string
- `on` string, required
- `when_matched_update_all` boolean
- `when_matched_update_all_filt` string
- `when_not_matched_insert_all` boolean
- `when_not_matched_by_source_delete` boolean
- `when_not_matched_by_source_delete_filt` string
- `timeout` string
- `use_index` boolean

## Response `200`

Result of merge insert operation

- MergeInsertIntoTableResponse — Response from merge insert operation
  - `transaction_id` string — Optional transaction identifier
  - `num_updated_rows` integer — Number of rows updated
  - `num_inserted_rows` integer — Number of rows inserted
  - `num_deleted_rows` integer — Number of rows deleted (typically 0 for merge insert)
  - `version` integer — The commit version associated with the operation

## Other responses

- `400` — Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware.
- `401` — Unauthorized. The request lacks valid authentication credentials for the operation.
- `403` — Forbidden. Authenticated user does not have the necessary permissions.
- `404` — A server-side problem that means can not find the specified resource.
- `503` — The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry.
- `5XX` — A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes.

## Changes

- **2025-12-20** `5d6099d672d3` — 6 breaking, 6 warning, 6 info
  - the `code` response property's min was decreased from `400.00` to `0.00` for the response status `400`
  - the `code` response property's min was decreased from `400.00` to `0.00` for the response status `401`
  - the `code` response property's min was decreased from `400.00` to `0.00` for the response status `403`
  - the `code` response property's min was decreased from `400.00` to `0.00` for the response status `404`
  - …14 more
- **2025-12-11** `6ad4337e3849` — 5 info
  - added the new optional `query` request parameter `timeout` to all path's operations
  - added the new optional `query` request parameter `use_index` to all path's operations
  - added the new optional `query` request parameter `timeout`
  - added the new optional `query` request parameter `use_index`
  - …1 more
- **2025-07-29** `40a3bc489d46` — 6 breaking, 12 warning, 12 info
  - the response property `type` became optional for the status `400`
  - the response property `type` became optional for the status `401`
  - the response property `type` became optional for the status `403`
  - the response property `type` became optional for the status `404`
  - …26 more
- …earlier changes not shown

[Full history](https://skmtc.dev/lance-format/apis/lance-namespace-specification/changes/v1/table/:id/merge_insert/post.md)

---

[API](https://skmtc.dev/lance-format/apis/lance-namespace-specification.md) · [All operations](https://skmtc.dev/lance-format/apis/lance-namespace-specification/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/lance-format/lance-namespace-specification/revisions/5d6099d672d3/schema)
