Writing rows
Add, update, and delete lookup-table rows with a Read and write API key.
Choose what the application can change
An organization admin grants Read & write in Settings → Integrations. Keys keep their existing permissions until an admin changes them. A key can write only tables and fields it can read. Rotation does not grant new permissions.
| Table | Allowed writes |
|---|---|
| A custom table your organization created | Add rows, update values, add or update by a lookup key, and delete rows. |
| A table synced from Attio or maintained by an app | Update your own fields on existing rows. The source controls row membership and synced values. |
To delete a row, set the table's field access to All fields. Selecting individual fields does not permit row deletion, even if you select every current field. Writes change lookup tables in Neon Deer, not Attio records. Use the separate table settings and field endpoints to change the table itself. Those operations need their own permissions.
Choose an operation
- Add a row when the row should not already exist.
- Update a row to change selected values in a known row.
- Add or update rows to match each item by a lookup key, updating a match or adding a row when none exists.
- Delete a row to remove it from a custom table.
Use field keys, not labels. Values follow the field's JSON type. An omitted field keeps its existing value; null clears it. An empty string is not a clearing instruction.
Avoid overwriting another change
Rows include a version. Send it as expected_version when an update or deletion must apply only to the version you read. Add-or-update items also accept this property when updating an existing row.
If the row has changed, the API returns 409 version_conflict. Read it again and decide whether your change is still appropriate. Omitting expected_version does not check for an intervening change.
Retry a write
Add a row and Add or update rows require Idempotency-Key. Generate a UUID for each new request and retain it with the exact request body. After an uncertain response, retry promptly with the same key, target, and body. While the original result remains available, the API returns it without repeating the write and includes Idempotent-Replayed: true.
Reusing a key with a different request returns 409 idempotency_conflict. An earlier result can also become unavailable, for example after a row it wrote is deleted. Do not assume request keys provide permanent deduplication. Inspect the table before sending a new request when the original outcome is uncertain.
PATCH and DELETE do not use this request-key mechanism. After an uncertain response, read the row before retrying. A version check can prevent a repeated update from overwriting a later change. A deleted row is no longer available to read.
Follow Retry-After for temporary errors. See Errors and Rate limits for recovery.
A field used for add-or-update must have a lookup. Create one with Add lookup before using it as key_field.
Check every item in an add-or-update response
By default, each item succeeds or fails independently. 200 means the request was accepted, even if individual items failed. Read data.summary and every entry in data.results. Successful items remain applied.
Set all_or_nothing: true when the entire request must succeed together. If any item would fail, the API returns 422 batch_rejected, writes nothing, and includes results identifying errors and items marked not_applied.
Try with test data
The Playground can send writes using the key's saved permissions. Its Send request control applies changes to the actual table, including immediate deletion without another confirmation. Use a custom table with disposable test rows, then read the affected rows back.