?translatable now takes the target locale id

The translatable parameter introduced on July 27 couldn’t express the workflow it was built for, so its shape has changed.

Why it changed

A translation integration reads the primary locale to get the source text, translates it, then writes the result to a secondary locale. As originally shipped, translatable=true resolved exclusion rules against the same localeId used to select the content, which left no way to do that first step correctly:

  • Requesting the primary locale returned the right content, but only matched exclusion rules scoped to “all languages” — rules scoped to a specific language were silently ignored, so you could receive content the site owner had excluded for the language you were translating into.
  • Requesting a secondary locale scoped the rules correctly, but returned content that was already translated rather than the source text.

What changed Breaking Change

translatable now takes the id of the secondary locale you’re translating into, independent of localeId:

?localeId={primary locale id}&translatable={target locale id}
  • translatable=true and translatable=false now return a 400. Pass a locale id, or omit the parameter entirely.
  • The value must be the id of one of the site’s secondary locales. The primary locale id, or any other value, returns a 400.
  • localeId is optional. Omitting it returns the primary locale’s content, filtered for the target locale — the common case for a translation integration.
  • The parameter requires translation exclusions to be enabled for the site. If they aren’t, the request returns a 403.
  • If the exclusion rules can’t be resolved, the request returns a 500 instead of unfiltered content. Retry the request.

Required action: if you’re passing translatable=true, replace it with the id of the locale you’re translating into. If you’re passing translatable=false, remove the parameter.

Affected endpoints:

Behavior that hasn’t changed: only exclusion rules scoped to manual translation are respected, and omitting translatable returns the same response as if the parameter didn’t exist.