---
title: "Edit a person row's field values"
method: PATCH
path: "/api/v1/ackdb/observe/persons/{personId}/fields"
tags: ["ackDB"]
---

# Edit a person row's field values

`PATCH /api/v1/ackdb/observe/persons/{personId}/fields`

## Request

- Base URL: `http://localhost:3009`
- URL: `http://localhost:3009/api/v1/ackdb/observe/persons/{personId}/fields`
- Auth: HTTP bearer

Person-grain equivalent of PATCH /observe/companies/{entityId}/fields (#329) - a batch { "<fieldKey>": <value>, … }. Only TWO kinds of field are editable on a human: `name` (a direct persons.name UPDATE) and the durable-key columns (`idl__<type>`, replace-the-set through the same layer `POST /persons/{personId}/links` uses - values are normalized, role inboxes refused, and a value owned by ANOTHER human is REFUSED and recorded as a merge candidate, never re-pointed (first-writer-wins)). Everything else is rejected per-field: there are no person traits, the rollups (affiliation_count, key_count, is_internal, last_active, companies, activity, event columns) are computed, and `status` is the identity lifecycle set by the merge endpoints. Partial success: valid fields apply, the rest (including key conflicts) come back in `errors`. An `idl__email_address` add DECLINED as a fallback (#575 — the person already holds a `linkedin_url` anchor) that changed nothing else is reported in `errors` as a per-field notice, never counted in `updated`: email is a fallback anchor, and this grain has no edge to store it on.

## Path parameters

- `personId` string, required

## Request body

- object: Field key → new value. Multiple fields allowed.

## Response `200`

The keys that were updated + a per-field error map for any that were rejected.

- AckdbObserveFieldEditResponse: Result of a direct field-value edit (#238). `updated` lists the field keys that were written; `errors` maps each field that was NOT written to a reason - an unknown field, a type/allowedValues violation, or a non-editable field (a computed/derived column, an append-only event/event-field column, or the internal `status` lifecycle enum).
  - `data` object, required
    - `updated` string[], required: Field keys successfully written.
    - `errors` object, required: Field key → rejection/validation reason for fields that were not written.

## Other responses

- `400`: Empty/non-object body, no field could be updated (`details.errors` per field), or the id is a MERGED (tombstoned) person - edit the survivor named in `details.mergedInto` (BAD_REQUEST).
- `404`: No person with that person_id (ENTITY_NOT_FOUND).

---

[API](https://skmtc.dev/floqer/apis/floqer-public-api.md) - [All operations](https://skmtc.dev/floqer/apis/floqer-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/floqer/apis/floqer-public-api/revisions/fce50dc07b20?raw)
