---
title: "Manage languages, glossary and static text"
method: POST
path: "/projects/{projectId}/localization"
tags: ["Languages and localization"]
---

# Manage languages, glossary and static text

`POST /projects/{projectId}/localization`

## Request

- Base URL: `https://studio.weaverse.io/api/v1/content`
- URL: `https://studio.weaverse.io/api/v1/content/projects/{projectId}/localization`
- Auth: HTTP bearer

Runs one localization operation, selected by `op`. Language and static text changes are live project state (no draft or publish step) and refresh the storefront cache. Glossary entries are translation aids, not storefront content.

Operations:

- `add-language` (`content:write`): adds a language by `code` and `languageCode` (2-35 characters each; `code` is lowercased). Re-adding an existing language is a no-op and returns `language: null`; re-adding a deleted one revives it with its translations.
- `delete-language` (`content:delete`, `confirm` equal to `languageId`): deletes a language under the project lock and advances the project revision, so drafts captured against the old language set are fenced. A missing or foreign id returns `404` with nothing written.
- `static-save` (`content:write`): merges `translations` (flattened key to value, e.g. `cart.title`) into language `languageId`'s static text. An empty string removes that key's value. Returns the number of keys sent.
- `static-key-default` (`content:write`): sets the default value of static key `keyId` (max 20,000 characters).
- `static-key-delete` (`content:delete`, `confirm` equal to `keyId`): deletes a static key.
- `glossary-upsert` (`content:write`): creates an entry, or updates entry `id` when given. `sourceTerm` (1-200 characters) is required; optional `doNotTranslate`, `caseSensitive` (both default `false`) and `notes` (max 2,000).
- `glossary-delete` (`content:delete`, `confirm` equal to `entryId`): deletes a glossary entry.

`delete-language` returns `cacheDelivery: "degraded"` when the delete committed but the cache refresh failed. A wrong `confirm` value returns `400 INVALID_PARAMS`.

Required scope: `content:write` (all operations); `delete-language`, `static-key-delete` and `glossary-delete` also need `content:delete`

## Request body

- union
  - object
    - `op` 'add-language', required
    - `code` string, required
    - `languageCode` string, required
  - object: Delete a language of this project (content:delete + confirm). Same project-authoritative protocol as Studio: recheck and delete under the project lock, advancing the project revision (fences drafts captured against the old language set). A missing or foreign id is 404 with nothing written.
    - `op` 'delete-language', required
    - `languageId` string, required
    - `confirm` string, required: Must equal the languageId
  - object
    - `op` 'glossary-upsert', required
    - `id` string
    - `sourceTerm` string, required
    - `doNotTranslate` boolean
    - `caseSensitive` boolean
    - `notes` string, nullable
  - object
    - `op` 'glossary-delete', required
    - `entryId` string, required
    - `confirm` string, required
  - object
    - `op` 'static-save', required
    - `languageId` string, required
    - `translations` object, required
  - object: Edit a static key default value (content:write).
    - `op` 'static-key-default', required
    - `keyId` string, required
    - `defaultValue` string, required
  - object: Delete a static key (content:delete + confirm).
    - `op` 'static-key-delete', required
    - `keyId` string, required
    - `confirm` string, required: Must equal keyId

## Response `200`

Operation result

- object

## Other responses

- `401`: Missing or invalid credentials
- `403`: Foreign project or missing scope (INSUFFICIENT_SCOPE)
- `404`: Not found (never discloses other tenants)

---

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