---
title: "Update Key"
method: PATCH
path: "/v1/mcp/projects/{project_id}/keys"
tags: ["mcp"]
---

# Update Key

`PATCH /v1/mcp/projects/{project_id}/keys`

## Request

- Base URL: `https://api.sonenta.dev`
- URL: `https://api.sonenta.dev/v1/mcp/projects/{project_id}/keys`
- Auth: none declared

Edit-in-place the SOURCE value of an existing key (task 862).

Patches the source-language value while PRESERVING the key + its history
(no delete+recreate). When the value actually changes, the key's existing
reviewed/approved target translations are demoted to `translated`
(needs-review / à revoir) and that count is surfaced. A real change bills
one unit; a no-op (submitted value == current) writes nothing and is not
billed.

## Path parameters

- `project_id` string, required

## Request body

- KeyUpdateIn: Edit-in-place the source value of an EXISTING key. Address it by uuid (preferred) OR namespace slug + name.
  - `source_value` string, nullable: New source-language value. OMIT for a retype-only call: the source value and every translation are then left strictly untouched. A type-reclassification tool must never have to send content it does not own.
  - `key_uuid` string, nullable: Target key uuid (preferred).
  - `namespace` string, nullable: ...or namespace slug (with name).
  - `name` string, nullable: ...key name (with namespace).
  - `description` string, nullable: Optional: also update the key's description.
  - `type` 'text' | 'heading' | 'label' | 'caption' | 'badge' | 'tooltip' | 'error_message' | 'toast' | 'button' | 'link' | 'menu_item' | 'input_placeholder' | 'input_label' | 'image' | 'icon' | 'meta_title' | 'meta_description', nullable: Optional: also retype the key (e.g. button, heading). A type-only change (same source_value) persists the new type WITHOUT touching the source value or translations, and is NOT billed (task 1421).
  - `type_source` 'default' | 'detected' | 'manual', nullable: Provenance of the retype: 'detected' when a mechanical code scan inferred it, 'manual' (the default) when it is a deliberate call. Drives the a11y detection coverage — see GET /a11y/detection.
  - `plurals` boolean, nullable: Optional: toggle whether this key is PLURAL. true makes it a plural key (its value carries CLDR forms one/few/…/other); false makes it a single value. Touches only the flag — not the source value or translations — and is not billed.

## Response `200`

Successful Response

- KeyUpdateOut
  - `key_uuid` string, required
  - `key_name` string, required
  - `namespace_uuid` string, required
  - `source_value` string, required
  - `result` string, required
  - `source_changed` boolean, required
  - `type_changed` boolean
  - `type_result` string
  - `plurals_changed` boolean
  - `stale_flagged` integer, required
  - `billable` boolean, required

## Other responses

- `422`: Validation Error

---

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