Batch Update Targets
const url = 'https://app.lionrapid.com/api/integrations/targets/batch';const options = { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: '{"translations":[{"key":"es:default:auto_abc123","value":{"styles":{},"text":"Hola mundo"}}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://app.lionrapid.com/api/integrations/targets/batch \ --header 'Content-Type: application/json' \ --data '{ "translations": [ { "key": "es:default:auto_abc123", "value": { "styles": {}, "text": "Hola mundo" } } ] }'Batch update target locale translations (editor saves).
Synchronous — editor batches are small and need immediate feedback. Each item writes to TargetRow (not SourceRow).
Args: batch_request: Batch of target translations with composite keys api_key: Integration API key for authentication
Returns: Created/updated/skipped counts
Example: PUT /targets/batch { “translations”: [ {“key”: “es:default:auto_abc123”, “value”: {“text”: “Hola”, “styles”: {}}} ] }
Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Header Parameters
Section titled “Header Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”Request for batch updating target translations (editor saves).
Each item uses composite key format: locale:namespace:key
object
List of target translations to save
Single translation item in batch sync request.
Accepts multiple input formats for value:
- Plain string: “Welcome” -> auto-wrapped to ContentUnit
- HTML string: “Click here” -> parsed to ContentUnit
- ContentUnit dict: {“text”: “…”, “styles”: {…}} -> used directly
object
Composite translation key in format ‘locale:namespace:key’ (e.g., ‘en:app:user.profile.name’)
ContentUnit format for styled translations.
Uses indexed tags format where styles are referenced by numeric indices. Example: {“text”: “Click <1>here</1>”, “styles”: {“1”: [“hyperlink:/home”]}}
object
Text with indexed tags like ‘Click <1>here</1>’
Style definitions by tag index, e.g., {‘1’: [‘bold’, ‘hyperlink:/path’]}
object
Responses
Section titled “Responses”Successful Response
Response for batch target translation updates.
object
Operation status
Number of new target rows created
Number of existing target rows updated
Number of items skipped (source row not found, or value could not be parsed). Note: invalid/unconfigured/source target locales now hard-fail the whole batch with a 400 rather than being skipped.
Number of rows the caller was not authorized to edit (can_user_edit_row)
Per-key outcomes for denied rows (editor-session callers only)
Per-key outcome for a batch item refused by per-row authorization.
The batch equivalent of the dashboard save’s 423 “locked” / 403 “forbidden”
rejection with a row snapshot: the client restores current_text in place
of the unsaved edit and explains reason to the user.
Rows rejected by the directive-parity gate (%n/%p format-string injection absent from the source)
Up to 50 rejected keys with reasons; other added directives are written but flagged as a directive_added QA finding
A row rejected by the directive-parity gate (H-3).
object
The composite key (locale:namespace:key) that was rejected
Why it was rejected, e.g. [‘printf_added’]
Rows a server-side (master/publishable-key) push declined to overwrite because a human committed them (#73). NOT counted in updated — the row was left as it was
Per-key outcomes for protected rows, so the operator learns which strings did not land
Per-key outcome for a row a server-side push declined to overwrite (#73).
Distinct from DeniedRowItem, which is about AUTHORIZATION — whether this caller may edit
this row. This is about AUTHORSHIP: a human committed the wording that is already there, and a
master/publishable-key push has no person in the loop to make that call. The push still
succeeds; the row is skipped and named here, so the operator who ran it learns their string did
not land. A silent skip would report success for work that did not happen.
Resolve it the way a human already can: edit the row in the editor, or use “Use for all”, both of which put a person on the record. There is deliberately no API force flag — if these turn up in practice, the use case gets discussed rather than guessed at.
Total items processed. Reconciles exactly: created + updated + skipped + denied + rejected + protected
Example
{ "created": 3, "denied": 1, "denied_rows": [ { "current_text": "Tervetuloa", "key": "fi:homepage:hero.title", "reason": "forbidden" } ], "rejected": 0, "rejected_keys": [], "skipped": 0, "status": "ok", "total": 5, "updated": 1}Validation Error
object
object
Examplegenerated
{ "detail": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ]}