Translations

Validate or apply a translation batch

Submits a batch of 1-50 translation units read from GET /projects/{projectId}/translation-units. {operation} is one of:

  • validate: runs every check (unit membership, value shape, placeholders, source and target generations, duplicates) and writes nothing. Returns object: "translation_validation" with a per-unit outcome of apply or unchanged.
  • apply: runs the same checks under the project lock, then writes only Translation rows, atomically. Returns object: "translation_apply" with applied/unchanged counts and an exact primary readback of every submitted unit. The cache is invalidated once; if that fan-out fails the write still stands and the response carries cacheDelivery: "degraded".

Any other {operation} value returns 404.

Each unit echoes id, sourceGeneration and targetGeneration exactly as listed (targetGeneration: null when no target was stored), plus translatedValue:

  • Text units take a string (max 20,000 characters). {{name}} and {name} placeholders in the source must appear unchanged in the translation.
  • Image units take { url, alt?, width?, height? }; url must be https:// or root-relative.
  • null clears the overlay so the source shows through. An empty string is rejected. Clearing an absent target, or re-clearing a cleared one, reports unchanged.

Concurrency and atomicity:

  • Any stale source or target refuses the whole batch with 409 STALE_TRANSLATION (details.unitId, details.side) and writes nothing. Re-read the inventory and resubmit.
  • A unit outside this project's writable content for the locale returns 404 TRANSLATION_UNIT_NOT_FOUND (details.unitId) and writes nothing.
  • A unit whose target already holds the requested value is unchanged regardless of the generation it carries, so an identical retry converges.
  • On apply, every submitted unit (including ones the preflight found unchanged) is re-proven against locked source and target state; a unit that moved between preflight and lock fails the whole batch.
  • Under the same lock, apply re-proves each unit's stored-schema approval (the field must still be a declared text input, or image input for an image unit, of its component type; otherwise 409) and the target's authority (the locale must still resolve to the same configured, non-default language; otherwise 400 or 409). Nothing is written in either case.

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 on the translation-unit routes.

Required scope: translations:write

post/projects/{projectId}/translations/{operation}

Request

  • Base URL
    https://studio.weaverse.io/api/v1/content
  • Auth
    HTTP bearer

Request body

targetLocalestring required

Response

translation_validation or translation_apply result

object required

Changes

No recorded changes to this operation across all 1 revision of this API.