Add or update rows
Match rows by a lookup key, update matches, and add missing rows.
Request
POST /v1/lookup-tables/{table_id}/rows/upsert
Adds or updates rows by a unique field: each item updates the row whose key_field holds its key, or adds a row. key_field must be a field with a lookup, which Add lookup makes. Each item succeeds or fails on its own and the answer is 200 even when some fail, so read every item's outcome. With all_or_nothing true, nothing is written if any item would fail: the answer is 422 batch_rejected, with every item's outcome in results. Needs an API key that can write. Values an update replaces are not kept, so it can't be undone.
Requires lookup_tables:write. The connection also needs access to the relevant tables, objects, or workflows.
MCP action: upsert_lookup_rows. Its argument names match the fields below; an HTTP header is passed using its argument name in MCP.
Parameters
| Name | Send in | Required | Type or allowed values | Notes |
|---|---|---|---|---|
table_id |
path | Yes | string | |
key_field |
JSON body | Yes | string | |
items |
JSON body | Yes | array of object | |
items[].key |
Within the JSON value | Within this object | string or number or boolean or object | |
items[].key.objectId |
Within the JSON value | Within this object | string (uuid) | Alternative 4. |
items[].key.recordId |
Within the JSON value | Within this object | string (uuid) | Alternative 4. |
items[].values |
Within the JSON value | Within this object | object | |
items[].expected_version |
Within the JSON value | No | integer | |
all_or_nothing |
JSON body | No | boolean | |
request_key |
Header: Idempotency-Key |
Yes | string |
Response
| HTTP status | Result |
|---|---|
200 |
One result per item, in the order sent, and how many were created, updated and failed. |
Required fields are required within their containing object. Notes identify fields that apply only to a particular response alternative.
| Response field | Type | Required in object | Notes |
|---|---|---|---|
data |
object | Yes | |
data.object |
"lookup_row_upsert" |
Yes | |
data.summary |
object | Yes | |
data.summary.created |
integer | Yes | |
data.summary.updated |
integer | Yes | |
data.summary.failed |
integer | Yes | |
data.results |
array of object | Yes | |
data.results[].index |
integer | Yes | |
data.results[].outcome |
"created" |
Yes | Alternative 1. |
data.results[].row |
object | Yes | Alternative 1. Alternative 2. |
data.results[].row.id |
string (uuid) | Yes | Alternative 1. Alternative 2. |
data.results[].row.object |
"lookup_row" |
Yes | Alternative 1. Alternative 2. |
data.results[].row.values |
object | Yes | Alternative 1. Alternative 2. |
data.results[].row.version |
integer | Yes | Alternative 1. Alternative 2. |
data.results[].row.roster_verified_at |
string (date-time) | No | Alternative 1. Alternative 2. |
data.results[].outcome |
"updated" |
Yes | Alternative 2. |
data.results[].outcome |
"error" |
Yes | Alternative 3. |
data.results[].error |
object | Yes | Alternative 3. |
data.results[].error.code |
string | Yes | Alternative 3. |
data.results[].error.message |
string | Yes | Alternative 3. |
data.results[].error.param |
string | No | Alternative 3. |
Errors
| HTTP status | Meaning |
|---|---|
400 |
One of: invalid_request, invalid_filter, invalid_value, invalid_cursor, credential_in_url. |
401 |
One of: missing_credential, invalid_credential, credential_expired, credential_revoked. |
402 |
One of: payment_overdue. |
403 |
One of: plan_required, not_available, insufficient_scope, operation_not_allowed, field_not_writable, plan_capacity_exceeded. |
404 |
One of: resource_not_found. |
409 |
One of: table_filling, table_fill_failed, lookup_key_required, key_conflict, version_conflict, table_busy, table_capacity_exceeded, idempotency_conflict. |
413 |
One of: request_too_large. |
422 |
batch_rejected: all_or_nothing was set and an item would fail. Nothing was written; results gives each item's error, or not_applied. |
423 |
One of: organization_reopening. |
428 |
One of: customer_agreement_required. |
429 |
One of: rate_limited. |
503 |
One of: service_unavailable. |
See errors and recovery and safe retries before repeating a write.
The public OpenAPI document lists generally available API families. Alpha operations may not appear in that document; their request and response fields are listed on this page. Use the API Playground to inspect a real response with your connection's access.