Skip to content

Batch Update Targets

PUT
/api/integrations/targets/batch
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”: {}}} ] }

surface
Any of:
string
x-api-key
Any of:
string
x-lr-surface
Any of:
string
Media typeapplication/json
TargetBatchUpdateRequest

Request for batch updating target translations (editor saves).

Each item uses composite key format: locale:namespace:key

object
translations
required
Translations

List of target translations to save

Array<object>
>= 1 items <= 1000 items
TranslationBatchItem

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
key
required
Key

Composite translation key in format ‘locale:namespace:key’ (e.g., ‘en:app:user.profile.name’)

string
>= 5 characters <= 500 characters /^[a-zA-Z0-9_-]+:[a-zA-Z0-9_-]+:.+$/
value
required
Any of:
string

Successful Response

Media typeapplication/json
TargetBatchUpdateResponse

Response for batch target translation updates.

object
status
required
Status

Operation status

string
created
required
Created

Number of new target rows created

integer
updated
required
Updated

Number of existing target rows updated

integer
skipped
required
Skipped

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.

integer
denied
Denied

Number of rows the caller was not authorized to edit (can_user_edit_row)

integer
0
denied_rows
Denied Rows

Per-key outcomes for denied rows (editor-session callers only)

Array<object>
DeniedRowItem

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.

object
key
required
Key

Composite key of the refused item (locale:namespace:key)

string
reason
required
Reason

“locked” (row locked, PM-only) or “forbidden” (not assigned to this row/stage)

string
current_text
Any of:
string
rejected
Rejected

Rows rejected by the directive-parity gate (%n/%p format-string injection absent from the source)

integer
0
rejected_keys
Rejected Keys

Up to 50 rejected keys with reasons; other added directives are written but flagged as a directive_added QA finding

Array<object>
TargetRejectedItem

A row rejected by the directive-parity gate (H-3).

object
key
required
Key

The composite key (locale:namespace:key) that was rejected

string
reasons
required
Reasons

Why it was rejected, e.g. [‘printf_added’]

Array<string>
protected
Protected

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

integer
0
protected_rows
Protected Rows

Per-key outcomes for protected rows, so the operator learns which strings did not land

Array<object>
ProtectedRowItem

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.

object
key
required
Key

Composite key of the skipped item (locale:namespace:key)

string
reason
required
Reason

Always “human_committed” today — a human authored, confirmed, approved or delivery-locked this row

string
current_text
Any of:
string
total
required
Total

Total items processed. Reconciles exactly: created + updated + skipped + denied + rejected + protected

integer
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

Media typeapplication/json
HTTPValidationError
object
detail
Detail
Array<object>
ValidationError
object
loc
required
Location
Array
msg
required
Message
string
type
required
Error Type
string
Examplegenerated
{
"detail": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
]
}