Customisers
publish_customiser_language
destructive writePublish customiser language
Put a translated language live on the storefront after the merchant has reviewed it and agreed.
Overview
Publishes one customiser language: its draft translations replace its published copy, which is what the live storefront serves. Publishing an already published language pushes its current drafts live again. It is refused with language_publish_blocked and the list of missing_keys while any required key has a blank draft, and while an AI translation is still writing the language. Publishing the authoring language also writes each changed option and form text to the customiser. The call requires confirm true and changes nothing without it; dry_run true checks the publish without changing anything. It requires the customisers:write scope and an idempotency_key.
Permission
Requires thecustomisers:writepermission. A connection without it answersinsufficient_scopenaming the permission to approve.
Annotations
Prerequisites
- A customiser id from list_customisers and a language code from list_customiser_languages.
- A draft value for every required key. get_customiser_language with include translations and the required filter shows the ones still blank.
- The merchant explicit agreement, sent as confirm true.
- A merchant has connected this store and approved the customisers:write scope.
Side effects
- Replaces the published copy of the language with its draft copy, which changes what shoppers see.
- For the authoring language, writes each changed option, selection, setting, letter-part and form text to the customiser.
- Clears the customiser cached storefront configuration and runs the language sync.
- Claims the idempotency_key for at least 24 hours.
Arguments
The customiser id, from list_customisers.
The BCP 47 language tag the language is addressed by, such as fr or pt-BR, from list_customiser_languages.
Must be true to apply the change, because the draft copy replaces the published copy and shoppers see it on the live storefront. Without it the call returns a confirmation_required error and changes nothing.
A client-generated key unique to this logical write, such as a UUID. Required: repeating the call with the same key and the same arguments replays the original result instead of writing twice, and the same key with different arguments is an idempotency_key_conflict.
When true, the publish is checked against the required copy, any running AI translation and, for the authoring language, the field rules of each changed text is checked and nothing is written: the result is the same verdict the apply would have reached, and a problem the apply would have raised comes back as the same tool error. Defaults to false. A dry run claims no key. A dry run does not require the confirm argument.
Result
The language record after the publish. A dry run returns the publish verdict instead and changes nothing.
The language after the publish. Absent on a dry run.
Present and true only when dry_run was requested.
Present only on a dry run, and always true: a failing dry run returns a tool error instead.
Present only on a dry run: the publish verdict.
True when this call replayed a previously recorded response for the same idempotency_key instead of applying the write again.
Error cases
An AI translation is still writing this language. Wait for it to finish, or stop it with cancel_customiser_language_translation, then retry.
Send confirm true once the merchant has agreed to publish. Nothing was published.
The language changed after the recorded publish. Issue a new key and re-check the language before writing again.
The connection was approved without customisers:write.
Required keys still have a blank draft. Write the keys in missing_keys with update_customiser_language_translations, then retry.
No customiser with that id, or no language with that code on it.
The language changed while the publish ran. Read it again and retry.
Publishing the authoring language would write a draft value that breaks its field rules, for example by being too long. Correct the named key and retry.
Publish a complete language the merchant approved
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "publish_customiser_language",
"arguments": {
"customiser_id": 42,
"language_code": "fr",
"confirm": true,
"idempotency_key": "b8c9d0e1-f2a3-4b45-8c67-d8e9f0a1b2c3"
}
}
}{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": {
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t",
"store": {
"id": 12,
"name": "Demo Signs"
},
"customiser_id": 42,
"language": {
"language_code": "fr",
"source_language_code": "en",
"display_name": "French",
"status": "published",
"is_default": false,
"is_authoring": false,
"translation_summary": {
"key_count": 184,
"required_key_count": 96,
"translated_key_count": 184,
"retired_key_count": 0,
"missing_required_key_count": 0,
"publishable": true
},
"ai_translation": null,
"published_at": "2026-05-04T10:02:00Z",
"updated_at": "2026-05-04T10:02:00Z"
},
"idempotent_replay": false
}
}
}Required copy is still blank (error)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "publish_customiser_language",
"arguments": {
"customiser_id": 42,
"language_code": "fr",
"dry_run": true
}
}
}{
"jsonrpc": "2.0",
"id": 1,
"result": {
"isError": true,
"structuredContent": {
"error": {
"code": "language_publish_blocked",
"title": "Language publish blocked",
"detail": "This language cannot be published while required copy is still blank. Write a draft value for every key in missing_keys, then retry. Stale values do not block publishing.",
"recovery": "Write a draft value for every key in missing_keys with update_customiser_language_translations, then publish again. Stale values do not block publishing.",
"missing_keys": [
"selection:12:title"
],
"missing_key_count": 1
}
}
}
}