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:
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
- Submit for translation: When a template is submitted, Courier sends a
notification:submitted webhook
- Fetch content: Your TMS fetches translatable content via the API
- Update translations: Push translated content back to Courier via the API
- Complete the process: Mark the translation as complete to release the template
Key Concepts
| Concept | Description |
|---|
| Blocks | Individual content pieces (text, action, list, etc.) that can have locale-specific versions |
| Channels | Channel-specific content (email subject, push title) that can be localized |
| Checksum | MD5 hash to track content changes and manage translation workflows |
| Locales | Language/region codes (e.g., fr_FR, de_DE) used to store translations |
Supported Block Types
| Block Type | Content Structure |
|---|
| Text | Plain string with variables and highlights |
| Quote | Plain string with variables and highlights |
| Markdown | Markdown string with variables |
| Action | Button text string |
| List | Object with parent and children strings |
| Template | HTML string |
API Endpoints
| Method | Endpoint | Description |
|---|
GET | /notifications/:id/draft/content | Fetch translatable content |
PUT | /notifications/:id/draft/locales | Update all locale content |
PUT | /notifications/:id/draft/locales/:locale | Update content for specific locale |
POST | /notifications/:id/draft/blocks/:blockId/locales | Update locales for specific block |
POST | /notifications/:id/draft/channels/:channelId/locales | Update locales for specific channel |
GET | /notifications/:id/:submissionId/checks | Get translation check status |
PUT | /notifications/:id/:submissionId/checks | Complete 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