---
title: "Set/clear attribute values on a contact"
method: PUT
path: "/api/v1/ackdb/contacts/{id}/attributes"
tags: ["ackDB"]
---

# Set/clear attribute values on a contact

`PUT /api/v1/ackdb/contacts/{id}/attributes`

## Request

- Base URL: `http://localhost:3009`
- URL: `http://localhost:3009/api/v1/ackdb/contacts/{id}/attributes`
- Auth: HTTP bearer

`:id` = contact id or email. Accepts contact-scope keys only. Same all-or-nothing validation, null-clears-DELETEs-the-row, and no-op-writes-emit-nothing semantics as the company variant; the `trait.updated` event lands on the contact's company timeline.

## Path parameters

- `id` string, required

## Request body

- AckdbAttributePutValuesRequest: Set/clear attribute values on one record. `null` clears a value (DELETEs the row). All-or-nothing: every key/value is validated before anything is written.
  - `values` object, required: Map of attribute key → new value (or null to clear). Must be non-empty.
  - `actor` string: Who made the change — recorded as the value row's updatedBy and the timeline event's actor (person.attribute.changed for people, trait.updated for companies/contacts). Defaults to "api". Observe/agent write paths stamp the real user automatically.

## Response `200`

{ entityId, contactId, applied: {key: value}, cleared: [key], updatedAt }.

- object
  - `data` unknown, required

## Other responses

- `400`: VALIDATION_ERROR — empty/invalid `values` object, or per-key failures; details: [{ key, error }]. Nothing is applied on any failure.
- `404`: CONTACT_NOT_FOUND.
- `409`: AMBIGUOUS_IDENTITY — the email matches more than one contact across entities; details: [{ contactId, entityId }] for each candidate. Retry with an explicit contactId.

---

[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)
