Overview of the Translations API introduced in revision 2026-04-15.
Before you begin
Check out our general API overview before getting started with specific endpoints.
The Translations API (revision 2026-04-15) is currently in Beta.
All endpoints in this overview require the
revision: 2026-04-15.preheader. The GA revision is planned for 2026-07-15. Endpoint paths and request/response shapes may change before GA.
The Translations API lets you manage multilingual content across campaigns, flows, templates, and universal content programmatically. While Klaviyo's Smart Translations feature provides an in-app localization experience, the Translations API gives you a "bring your own translation" path: export source strings, translate them using your own tools or Translation Management System (TMS), and import the results back into Klaviyo.
When calling the Translations API, your authentication key must have the appropriate scopes:
translations:readfor GET operations,translations:writefor POST, PATCH, and DELETE operations.
Use cases
The Translations API supports the following use cases:
- TMS integration: Export source content from Klaviyo, send it to an external TMS (e.g., Smartling, Phrase, Lokalise), and import the translated strings back, without reverse-engineering template HTML.
- Bulk translation management: List all translations across your account, filter by channel or resource type, and audit which resources are localized.
- Translation setup automation: Programmatically enable translations on campaigns, flows, templates, or universal content, setting source locale, target locales, and fallback locale.
- Localized content updates: Update translation settings (add or remove target locales) or import new translated values for existing translations.
- Translation cleanup: Delete translation collections when they are no longer needed.
Supported channels and resources
The Translations API supports the following channel and resource combinations:
| Resource type | Supported channels | Description |
|---|---|---|
campaign-variation | email, sms, mobile_push | A variation of a campaign message. |
flow-message | email, sms, mobile_push | A message within a flow. |
template | email, whatsapp | A reusable email or WhatsApp template. |
template-universal-content | email | A universal content block used across templates. |
WhatsApp templates have additional constraints: translations can only be created, updated, or deleted when the WhatsApp template is in DRAFT status, due to Meta's approval workflow.
Data model
A translation has the following structure:
-
idA composite identifier, for example
campaign-variation::email::01KH00000000000000000000AB. -
attributes-
source_localeThe BCP 47 locale code of the original source content (e.g.,
"en"). -
target_localesAn array of locale codes that the content is translated into (e.g.,
["fr", "es", "de"]). Must contain at least one item. -
fallback_localeThe locale used when translated content is unavailable for a target locale at render time (e.g.,
"en"). -
channelThe communication channel:
email,sms,mobile_push, orwhatsapp. -
metadataOptional, channel-specific metadata.
nullby default. Populated for WhatsApp translations with Meta-specific information such as template approval status. -
createdISO 8601 timestamp of when the translation was created.
-
updatedISO 8601 timestamp of when the translation was last modified.
-
values(additional field)An array of translatable content blocks with their translations. Only returned when you request
additional-fields[translation]=valueson a Get Translation request. Not available on the list endpoint. See Export and import translation values for details.
-
-
relationshipsEach translation has exactly one relationship to the Klaviyo resource it belongs to. The relationship key matches the resource type:
campaign-variation,flow-message,template, ortemplate-universal-content.
Quick start: export and import workflow
A typical export-translate-import workflow looks like this:
Step 1: Find the translation for your resource.
curl --request GET \
--url 'https://a.klaviyo.com/api/translations/?filter=equals(related_resource_id,"YOUR_RESOURCE_ID")' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'revision: 2026-04-15.pre'
Step 2: Export the translation values.
curl --request GET \
--url 'https://a.klaviyo.com/api/translations/campaign-variation::email::01KH00000000AB?additional-fields[translation]=values' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'revision: 2026-04-15.pre'
The response includes the values array with source content and existing translations:
{
"data": {
"id": "campaign-variation::email::01KH00000000AB",
"type": "translation",
"attributes": {
"source_locale": "en",
"target_locales": ["fr", "es"],
"fallback_locale": "en",
"channel": "email",
"metadata": null,
"created": "2026-03-01T12:00:00+00:00",
"updated": "2026-03-15T09:30:00+00:00",
"values": [
{
"id": "scheduled_message::01KH00000000AB::subject",
"source_value": "Spring Sale starts now!",
"translations": {
"fr": "",
"es": ""
}
},
{
"id": "scheduled_message::01KH00000000AB::body",
"source_value": "Shop our biggest sale of the season.",
"translations": {
"fr": "",
"es": ""
}
}
]
},
"relationships": {
"campaign-variation": {
"data": {
"type": "campaign-variation",
"id": "01KH00000000AB"
}
}
},
"links": {
"self": "https://a.klaviyo.com/api/translations/campaign-variation::email::01KH00000000AB"
}
}
}
Empty strings (
"") in thetranslationsobject indicate that a translation has not yet been provided for that locale.
Step 3: Translate the content using your TMS, translation team, or any tool of your choice.
Step 4: Import the translated values by sending a PATCH request with the updated values array. The payload format is symmetric with the export: you can take the exported values, fill in the translations, and send them back.
curl --request PATCH \
--url 'https://a.klaviyo.com/api/translations/campaign-variation::email::01KH00000000AB' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'revision: 2026-04-15.pre' \
--data '{
"data": {
"type": "translation",
"id": "campaign-variation::email::01KH00000000AB",
"attributes": {
"values": [
{
"id": "scheduled_message::01KH00000000AB::subject",
"translations": {
"fr": "Les soldes de printemps commencent maintenant !",
"es": "Las rebajas de primavera empiezan ahora!"
}
},
{
"id": "scheduled_message::01KH00000000AB::body",
"translations": {
"fr": "Profitez de nos plus grandes promotions de la saison.",
"es": "Compra en nuestra mayor venta de la temporada."
}
}
]
}
}
}'
Partial imports
Import is a partial update: only the content blocks and locales you include in the
valuesarray are updated. Omitted blocks and locales remain unchanged. Re-importing the same translations is safe and idempotent.
target_localesis a full replacementUnlike
values, thetarget_localesattribute is not additive. Sending"target_locales": ["it"]replaces the entire list, removing any previously set locales. To add a locale, include all existing locales in the array. For example, if your current targets are["es", "fr"]and you want to add Italian, send"target_locales": ["es", "fr", "it"].Note that removing a locale from
target_localesdoes not delete its translation values. If you have translations for["es", "fr"]and update to["it"], theesandfrvalues are retained. Updating back to["es", "fr", "it"]restores access to all three locales with their existing translations intact.
Create a translation
To enable translations on a resource, send a POST request to Create Translation. You must specify exactly one relationship to identify the resource being translated.
curl --request POST \
--url 'https://a.klaviyo.com/api/translations/' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'revision: 2026-04-15.pre' \
--data '{
"data": {
"type": "translation",
"attributes": {
"source_locale": "en",
"target_locales": ["fr", "es"],
"fallback_locale": "en",
"channel": "email"
},
"relationships": {
"campaign-variation": {
"data": {
"type": "campaign-variation",
"id": "01KFXS23TVJH0ZWPZW644CRV"
}
}
}
}
}'
{
"data": {
"id": "campaign-variation::email::01KFXS23TVJH0ZWPZW644CRV",
"type": "translation",
"attributes": {
"source_locale": "en",
"target_locales": ["fr", "es"],
"fallback_locale": "en",
"channel": "email",
"metadata": null,
"created": "2026-04-15T12:00:00+00:00",
"updated": "2026-04-15T12:00:00+00:00"
},
"relationships": {
"campaign-variation": {
"data": {
"type": "campaign-variation",
"id": "01KFXS23TVJH0ZWPZW644CRV"
}
}
},
"links": {
"self": "https://a.klaviyo.com/api/translations/campaign-variation::email::01KFXS23TVJH0ZWPZW644CRV"
}
}
}
A resource can only have one translation collection. Attempting to create a translation for a resource that already has one returns a
409 Conflicterror.
Update translation settings
Use Update Translation to modify translation settings such as adding or removing target locales. All attributes are optional in a PATCH request.
curl --request PATCH \
--url 'https://a.klaviyo.com/api/translations/campaign-variation::email::01KFXS23TVJH0ZWPZW644CRV' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'revision: 2026-04-15.pre' \
--data '{
"data": {
"type": "translation",
"id": "campaign-variation::email::01KFXS23TVJH0ZWPZW644CRV",
"attributes": {
"target_locales": ["fr", "es", "de"]
}
}
}'
If you change
source_localeto a locale that is currently intarget_locales, that locale is automatically removed from the target list.
Export and import translation values
Export values
To export translation values, use the additional-fields[translation]=values query parameter on a Get Translation request. This returns the values attribute containing each translatable content block with its source text and current translations.
curl --request GET \
--url 'https://a.klaviyo.com/api/translations/flow-message::email::01KGABCDEF?additional-fields[translation]=values' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'revision: 2026-04-15.pre'
Each item in the values array has:
id— The identifier for the translatable content block.source_value— The original text in the source locale.translations— A map of target locale codes to their translated strings. Empty strings indicate missing translations.
The
additional-fields[translation]=valuesparameter is only supported on the Get Translation (single resource) endpoint. It is not yet supported on Get Translations (list endpoint) and will return a400error if used there.
Import values
To import translations, include a values array in the attributes of a PATCH request to Update Translation. The import format mirrors the export format for payload symmetry: you can export, edit, and re-import with minimal transformation.
Each value object contains:
id(required) — Must match a valid translatable content block ID from the export.source_value(optional) — The original source text. Not required for import, but included in the export response, so you can pass it through as-is.translations(required) — A map of locale codes to translated strings. Only the locales you include are updated.
curl --request PATCH \
--url 'https://a.klaviyo.com/api/translations/flow-message::email::01KGABCDEF' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'revision: 2026-04-15.pre' \
--data '{
"data": {
"type": "translation",
"id": "flow-message::email::01KGABCDEF",
"attributes": {
"values": [
{
"id": "flow_message::01KGABCDEF::subject",
"translations": {
"fr": "Bienvenue !",
"de": "Willkommen!"
}
}
]
}
}
}'
Delete a translation
To remove translations from a resource, use Delete Translation. This removes the translation collection and all associated localized values.
curl --request DELETE \
--url 'https://a.klaviyo.com/api/translations/campaign-variation::email::01KFXS23TVJH0ZWPZW644CRV' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'revision: 2026-04-15.pre'
A successful deletion returns 204 No Content.
Querying translations
Use the Get Translations list endpoint to find translations across your account. Check out the supported query parameters below:
| Parameter | Description | Query example |
|---|---|---|
filter | Retrieve a subset of translations. Supported filter fields: id, resource_type, channel, related_resource_id. Learn about the filter query parameter. | GET /api/translations?filter=equals(channel,"email")GET /api/translations?filter=equals(related_resource_id,"01KFXS23TVJH") |
sort | Sort translations. Supported field: id. Prefix with - for descending. Learn about the sort query parameter. | GET /api/translations?sort=idGET /api/translations?sort=-id |
fields | Request only specified translation data. Learn more about sparse fieldsets. | GET /api/translations?fields[translation]=source_locale,target_locales,channel |
include | Include related resources in the response (e.g., campaign-variation, flow-message, template, template-universal-content). Learn about the include query parameter. | GET /api/translations?include=campaign-variation |
page[size] | Number of results per page (default: 20, max: 100). | GET /api/translations?page[size]=50 |
page[cursor] | Cursor for paginating through results. | GET /api/translations?page[cursor]=abc123 |
Filtering examples
Get all email translations:
curl --request GET \
--url 'https://a.klaviyo.com/api/translations/?filter=equals(channel,"email")' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'revision: 2026-04-15.pre'
Get the translation for a specific resource:
curl --request GET \
--url 'https://a.klaviyo.com/api/translations/?filter=equals(related_resource_id,"01KFXS23TVJH0ZWPZW644CRV")' \
--header 'Authorization: Klaviyo-API-Key your-private-api-key' \
--header 'accept: application/json' \
--header 'revision: 2026-04-15.pre'
Relationship endpoints
Each translation exposes a read-only relationship endpoint for the associated Klaviyo resource:
GET /api/translations/{id}/campaign-variation/GET /api/translations/{id}/flow-message/GET /api/translations/{id}/template/GET /api/translations/{id}/template-universal-content/
These return the related resource data, useful for navigating from a translation back to the content it belongs to.