Add or update rows
This is how you add rows to a table. New rows are inserted and, by
default, start enriching immediately; rows that match an existing row
on matchColumns update that row instead. This is v2’s only row-write
endpoint — there is no separate insert (to insert only, upsert with
matchColumns that nothing matches).
Each call runs as a batch, idempotent per batchId, and records per-row
inserted/updated/skipped outcomes you can read back with
GET /batches/{batchId}.
- Row keys and
matchColumnsare input column slugs (fromGET /tables/{tableId}/columns→columns[].slug), never display names. A non-slug row key →UNKNOWN_FIELDS. matchColumns(required) must be real input columns (UNKNOWN_COLUMN) and every match value must be present + non-empty on every row (MISSING_MATCH_VALUE).- Duplicate request keys →
DUPLICATE_MATCH_KEY; multiple existing rows match one key →AMBIGUOUS_MATCH(409). enrich(default true) enriches freshly inserted rows.reenrichUpdated(default false) — set true to also re-run enrichment on rows the upsert updated (re-spends credits); off by default so an upsert never silently re-enriches matched rows.
Only input-kind columns are writable. Enrichment, score, and
sequence columns are populated automatically — sequences are
agent/column-generated only (see POST /tables/{tableId}/sequences),
never set via this endpoint; passing one returns NON_INPUT_COLUMNS.
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Response
Idempotent replay of an existing batchId.