curl --request GET \
--url https://studio.weaverse.io/api/v1/content/projects/{projectId}/translation-units \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://studio.weaverse.io/api/v1/content/projects/{projectId}/translation-units', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://studio.weaverse.io/api/v1/content/projects/{projectId}/translation-units"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"object": "list",
"projectId": "clz8k2m4n0001qwer7tyu8iop",
"language": {
"id": "clz8k2x7y0003lkjh4gfd3sap",
"code": "fr-fr",
"name": "French"
},
"data": [
{
"id": "Y2x6OGszYzlkMDAwN3p4Y3Y4Ym5tMXF3ZQBkYXRhLmhlYWRpbmc",
"format": "plain_text",
"source": {
"locale": "en-us",
"value": "Summer collection",
"generation": "sha256:aNCJfb2kY7k558Hq_scUZeouHvrUoY9eaCam_HIB0hk"
},
"target": {
"locale": "fr-fr",
"value": "Collection été",
"generation": "sha256:zzj5orBWLJCO5eaC_y6jzBO285hKHUQCL5G_-PIhc3A",
"status": "current"
},
"context": {
"pageType": "INDEX",
"handle": "index",
"section": "Heading"
},
"usages": [
"/"
]
},
{
"id": "Y2x6OGszZDJlMDAwOHBvaXU3eXRyNmV3cQBkYXRhLmJ1dHRvblRleHQ",
"format": "plain_text",
"source": {
"locale": "en-us",
"value": "Shop now",
"generation": "sha256:i5yxt6P8d6YAZqFxmfpJwVd1EG3A-S_s04MP3XTKlHs"
},
"target": {
"locale": "fr-fr",
"value": null,
"generation": null,
"status": "missing"
},
"context": {
"pageType": "INDEX",
"handle": "index",
"section": "Button text"
},
"usages": [
"/"
]
}
],
"hasMore": true,
"nextCursor": "Y2x6OGszZDJlMDAwOHBvaXU3eXRyNmV3cQBkYXRhLmJ1dHRvblRleHQ",
"summary": {
"current": 18,
"missing": 5,
"stale": 2,
"excluded": 1
}
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}List translation units for a target locale
Project-wide translation inventory for one target locale: every unit an agent may translate, with opaque ids, source and target generations, context, storefront usages and a status summary. This is the first step of the translation-unit workflow:
GET /translation-units?targetLocale=…(optionallystatus=missing,stale) and page withafter=<nextCursor>whilehasMoreistrue.POST /translations/validatewith the units you translated: every check runs, nothing is written, and each unit reportsapplyorunchanged.POST /translations/applywith the same body: the checks re-run under the project lock and the batch is written atomically (compare-and-set on both generations).- Use the
readbackin the apply response, or list again, to confirm.
What is listed:
- Units of the pages the target locale actually renders, resolved with the storefront cascade. Items shared by several pages (global sections) appear once, with every route in
usages. - Only fields the stored project schema approves: text, richtext and textarea inputs and their defaults. Components without a stored schema, and fields of other input types, are never listed or writable.
kind=text(default) lists text units;kind=imagelists per-locale image overrides at declared image inputs, on the same protocol with an image object as the value.summarycountscurrent,missingandstaleacross all units of the requested kind (before thestatusfilter), plusexcluded: pages the locale renders that this project cannot write (inherited from a parent project or shared with another project).- A target is
missingwhen no row exists or it was cleared, andstalewhen the stored translation answers a source that has since changed. usageslists only concrete storefront paths and may be empty for templates, articles and system pages. Paths use the default route prefixes; a custom page prefix configured in Studio is not reflected.
Behaviour:
- Ordering is deterministic (by unit id).
limitis 1-100 (default 100);afteris a strict lower bound, so a cursor naming a unit that has since disappeared still resumes correctly. statusaccepts a comma-separated list or repeated parameters.targetLocalemust be a configured, non-default language (400 otherwise).- Uncached by design: it carries the generations a write compare-and-sets against.
Authentication: accepts shop API keys, scoped API keys and delegated MCP OAuth tokens that hold the scope, and project-bound translation agent tokens (wv_agent_…, Authorization header only). Agent tokens are accepted only by this route and POST /translations/{operation}; a token bound to another project gets 403.
Required scope: translations:read
curl --request GET \
--url https://studio.weaverse.io/api/v1/content/projects/{projectId}/translation-units \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://studio.weaverse.io/api/v1/content/projects/{projectId}/translation-units', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://studio.weaverse.io/api/v1/content/projects/{projectId}/translation-units"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"object": "list",
"projectId": "clz8k2m4n0001qwer7tyu8iop",
"language": {
"id": "clz8k2x7y0003lkjh4gfd3sap",
"code": "fr-fr",
"name": "French"
},
"data": [
{
"id": "Y2x6OGszYzlkMDAwN3p4Y3Y4Ym5tMXF3ZQBkYXRhLmhlYWRpbmc",
"format": "plain_text",
"source": {
"locale": "en-us",
"value": "Summer collection",
"generation": "sha256:aNCJfb2kY7k558Hq_scUZeouHvrUoY9eaCam_HIB0hk"
},
"target": {
"locale": "fr-fr",
"value": "Collection été",
"generation": "sha256:zzj5orBWLJCO5eaC_y6jzBO285hKHUQCL5G_-PIhc3A",
"status": "current"
},
"context": {
"pageType": "INDEX",
"handle": "index",
"section": "Heading"
},
"usages": [
"/"
]
},
{
"id": "Y2x6OGszZDJlMDAwOHBvaXU3eXRyNmV3cQBkYXRhLmJ1dHRvblRleHQ",
"format": "plain_text",
"source": {
"locale": "en-us",
"value": "Shop now",
"generation": "sha256:i5yxt6P8d6YAZqFxmfpJwVd1EG3A-S_s04MP3XTKlHs"
},
"target": {
"locale": "fr-fr",
"value": null,
"generation": null,
"status": "missing"
},
"context": {
"pageType": "INDEX",
"handle": "index",
"section": "Button text"
},
"usages": [
"/"
]
}
],
"hasMore": true,
"nextCursor": "Y2x6OGszZDJlMDAwOHBvaXU3eXRyNmV3cQBkYXRhLmJ1dHRvblRleHQ",
"summary": {
"current": 18,
"missing": 5,
"stale": 2,
"excluded": 1
}
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}{
"object": "error",
"code": "UNAUTHORIZED",
"message": "<string>",
"status": 123,
"details": "<unknown>"
}Authorizations
Bearer authentication: a shop API key (WEAVERSE_API_KEY), a scoped API key, a delegated MCP OAuth token, or (translation-unit routes only) a project-bound translation agent token. Scopes: content:read — Read projects, pages, theme settings, versions, drafts and translation units. content:write — Save drafts and make non-destructive edits (page items, metadata, SEO, assignments, languages, glossary). Never publishes or deletes. content:publish — Publish drafts, schedule/reschedule/cancel publications, restore versions, publish global sections. content:delete — Delete pages, global sections, languages, static keys, override reverts; required with project:manage for project deletion. project:manage — Create/copy/delete projects, settings, variants, hierarchy, backups, restore-as-new, previews, hostname policy. translations:read — Read translation units only (no general content access). translations:write — Apply translation units only; never mutates page content. A legacy unscoped API key keeps read/write/translation baseline access and every pre-scope endpoint, but never gains publish/delete/project-manage implicitly.
Path Parameters
Query Parameters
text, image Comma-separated or repeated
current, missing, stale 1 <= x <= 100Response
Deterministic, cursor-paged units with summary
The response is of type object.
Was this page helpful?