Operations
Translations
Every locale an entity is translated into, with the translated values per store, plus the catalog of fields that can carry a translation. Grouped by locale, then by store.
The two translation reads
/api/v1/products/{id}/translationspim:readA product's translations: every locale it is translated into, the translated values per store, and the catalog of fields that can carry a translation.
/api/v1/collections/{id}/translationspim:readA collection's translations, in the same shape.
Both take the entity's id as their only parameter and answer
404 not_found for an id from another account or of a different kind
of entity. The result is bounded by locales × stores, so the whole set is
returned — there is no cursor and nothing to paginate.
Example
curl "https://api.peak-pim.com/api/v1/products/5b2e9c1a-7d4f-4a8b-9e6c-3f1d8a5b2c70/translations" \
-H "Authorization: Bearer $PEAK_PIM_KEY"
Response — 200
{
"entity_id": "5b2e9c1a-7d4f-4a8b-9e6c-3f1d8a5b2c70",
"entity_type": "product",
"translatable_fields": [
{ "key": "title", "shopify_key": "title", "label": "Title" },
{ "key": "body_html", "shopify_key": "body_html", "label": "Description" },
{
"key": "metafield:custom:care_instructions",
"shopify_key": "value",
"label": "Care instructions",
"reference": "Machine wash cold. Do not tumble dry."
}
],
"locales": [
{
"locale": "fr",
"stores": [
{
"store_id": "1e8e4c2a-9f3b-4d7c-8a5e-6b2d9c1f7a30",
"store_domain": "acme-eu.myshopify.com",
"values": [
{ "key": "title", "value": "T-shirt en coton bio", "type": "single_line_text_field" }
],
"pending_publish": true,
"last_publish_status": "pending"
}
]
},
{
"locale": "de",
"stores": [
{
"store_id": "1e8e4c2a-9f3b-4d7c-8a5e-6b2d9c1f7a30",
"store_domain": "acme-eu.myshopify.com",
"values": [
{ "key": "title", "value": "Bio-Baumwoll-T-Shirt", "type": "single_line_text_field" }
],
"pending_publish": false,
"last_publish_status": "published"
}
]
}
]
}
The response shape
| Field | Type | Description |
|---|---|---|
entity_id | uuid | The entity the translations belong to. |
entity_type | string | What kind of entity it is. |
translatable_fields | array | The catalog of fields that can carry a translation — see below. |
locales | array | One group per locale, each holding per-store translations. |
Each translatable field describes one row of that catalog:
| Field | Type | Description |
|---|---|---|
key | string | The field key a translated value is written under. The only guaranteed field. |
shopify_key | string | The same field as Shopify names it. |
label | string | Human-readable label. |
reference | string | The source value this row translates, when it is not on the entity itself. |
Inside locales, each group carries:
| Field | Type | Description |
|---|---|---|
locale | string | BCP-47 language code, e.g. fr. |
stores[].store_id / store_domain | uuid / string | Which store the translated values live on. |
stores[].values | array | The translated values, as {key, value, type} triples keyed by the translatable field's key. |
stores[].pending_publish | boolean | This locale has unpublished translation changes on this store. |
stores[].last_publish_status | enum | never_published, pending, published, or failed. |
translatable_fields is what could be translated;
locales[].stores[].values is what is. A localization
integration diffs the two to find missing translations per locale per store —
or reads the translation dimensions of data health
for the account-wide picture.
Notes
- Part of the 2026-07-31 operations surface (private beta).
- Publish state is tracked per locale per store —
pending_publish: truemeans translated values exist that have not reached that store yet. - For which markets and locales a store serves, see Markets and the translations & markets guide.