Skip to main content

Overview

Courier supports sending notifications in multiple languages. You can localize your notifications using several approaches depending on your needs:
  • Manual approaches: Create language-specific channels or templates in the designer
  • Variable-based: Pass translated content in your send request
  • API-driven: Integrate with translation management systems (TMS) for automated workflows
For step-by-step instructions on implementing localization, see How to Internationalize Notifications.

Setting a User’s Locale

To send localized content, include a locale property in the user’s profile:
{
  "message": {
    "to": {
      "email": "[email protected]"
    },
    "template": "TEMPLATE_ID",
    "data": {
      "name": "Jane"
    }
  },
  "profile": {
    "locale": "fr_FR"
  }
}
The locale value should follow ISO 639-1 format (e.g., en, en_US, fr, fr_FR, de_DE).

Previewing Localized Content

When previewing a notification, include a locale in your test event’s profile to see the localized version:
Localized preview
Without a locale in the test event, the preview shows the default (source) language.

API-Driven Localization

API-driven localization is available on Business and Enterprise plans.
For teams using translation management systems (TMS), Courier provides APIs to programmatically manage translations.

How It Works

  1. Submit for translation: When a template is submitted, Courier sends a notification:submitted webhook
  2. Fetch content: Your TMS fetches translatable content via the API
  3. Update translations: Push translated content back to Courier via the API
  4. Complete the process: Mark the translation as complete to release the template
Internationalization workflow diagram

Key Concepts

ConceptDescription
BlocksIndividual content pieces (text, action, list, etc.) that can have locale-specific versions
ChannelsChannel-specific content (email subject, push title) that can be localized
ChecksumMD5 hash to track content changes and manage translation workflows
LocalesLanguage/region codes (e.g., fr_FR, de_DE) used to store translations

Supported Block Types

Block TypeContent Structure
TextPlain string with variables and highlights
QuotePlain string with variables and highlights
MarkdownMarkdown string with variables
ActionButton text string
ListObject with parent and children strings
TemplateHTML string

API Endpoints

MethodEndpointDescription
GET/notifications/:id/draft/contentFetch translatable content
PUT/notifications/:id/draft/localesUpdate all locale content
PUT/notifications/:id/draft/locales/:localeUpdate content for specific locale
POST/notifications/:id/draft/blocks/:blockId/localesUpdate locales for specific block
POST/notifications/:id/draft/channels/:channelId/localesUpdate locales for specific channel
GET/notifications/:id/:submissionId/checksGet translation check status
PUT/notifications/:id/:submissionId/checksComplete translation check
For full API details, see the API Reference.

Content Structure

When fetching content, each block includes:
{
  "id": "block_43c114d9-9cfd-4340-808f-17e2fc7a4c87",
  "type": "text",
  "content": "Hello <variable id=\"3\">{name}</variable>, Welcome to Courier!",
  "checksum": "fb60f2098fa407a4ff8d48e3e908d889",
  "locales": {
    "fr_FR": "Bonjour <variable id=\"3\">{name}</variable>, bienvenu à Courier!"
  }
}
When updating translations, preserve the <variable> and <highlight> tags with their original IDs. These are required for proper variable substitution.

Webhooks

Configure webhooks in Settings → Webhooks to receive notifications when:
  • notification:submitted - Template submitted for translation
  • notification:published - Template published
  • notification:canceled - Submission canceled