Appearance
Generic Translations API — API Analysis (API-A)
Concept layer — frozen. The Translations generic. Nothing here is written by a normal playbook run; a project's own feature analysis is the live document and takes every edit. This layer names no project and links to none — the dependency runs one way, from an application to its concept.
Feature: Translations · Entity: translations
Paths below are written without any version or gateway prefix: how a project versions and mounts the routes is an application decision, not part of the concept. Success envelope: { data, status, message, requestId }.
1. Add / Update Translation
Endpoint: POST /translations
Request Headers
json
{
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}Request Body
json
{
"locale": "cs-CZ",
"translationKey": "dashboard.title",
"translation": "Přehled",
"translationType": "entities",
"components": ["system"],
"active": true
}Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
translationKey | String | Yes | Unique translation key |
locale | String | Yes | Locale, in BCP 47 hyphenated form (for example cs-CZ) |
translation | String | Yes | Localized value |
translationType | String | Yes | Grouping based on the translation type |
components | Text[] | Yes | Grouping based on the system components |
active | Boolean | Yes | Flag for active / inactive translation |
Request Logic
- Check for an existing
translationKey+locale+translationType. - If it exists → update the record,
updatedAtandupdatedBy. - Otherwise → insert a new record.
Success Response (200 OK)
json
{
"data": {
"id": "018e69f3-df9e-7d1f-b2c4-91b462f2f4c2",
"locale": "cs-CZ",
"translationKey": "dashboard.title",
"translation": "Přehled",
"translationType": "entities",
"components": ["system"],
"active": true,
"createdAt": "2025-03-16T18:00:00Z",
"updatedAt": "2025-03-16T18:00:00Z",
"deletedAt": null,
"createdBy": "user:012e69f3-df9e-7d1f-b2c4-91b462f2f4c2",
"updatedBy": "user:012e69f3-df9e-7d1f-b2c4-91b462f2f4c2"
},
"status": 200,
"message": "Translation successfully created or updated.",
"requestId": "022e69f3-df9e-7d1f-b2c4-91b462f2f4c2"
}Response Data Mapping
| Field | Source |
|---|---|
data.id | translations.id |
data.locale | translations.locale |
data.translationKey | translations.translationKey |
data.translation | translations.translation |
data.translationType | translations.translationType |
data.components | translations.components |
data.active | translations.active |
data.createdAt | translations.createdAt |
data.updatedAt | translations.updatedAt |
data.deletedAt | translations.deletedAt |
data.createdBy | translations.createdBy |
data.updatedBy | translations.updatedBy |
status | 200 |
message | Translation successfully created or updated. |
requestId | Generated UUID |
2. Get Translations
Endpoint:
text
GET /translations?locale=$locale&components={$component1,$component2}
&translationType=$translationType&translation=$translation&translationKey=$translationKeyQuery Parameters
All the parameters correspond to the entity fields.
Request Logic
Returns the translations as a map, where the key is always the value of the locale field.
sql
SELECT * FROM translations t
WHERE t.locale = :locale
AND :component = ANY (t.components)
AND t.translationType = :translationType
AND t.deletedAt IS NULLSuccess Response (200 OK)
json
{
"data": {
"en-GB": [
{
"id": "018e69f3-df9e-7d1f-b2c4-91b462f2f4c2",
"locale": "en-GB",
"translationKey": "dashboard.title",
"translation": "Dashboard",
"translationType": "entities",
"components": ["system"],
"active": true,
"createdAt": "2025-03-16T18:00:00Z",
"updatedAt": "2025-03-16T18:00:00Z",
"deletedAt": null,
"createdBy": "user:012e69f3-df9e-7d1f-b2c4-91b462f2f4c2",
"updatedBy": "user:012e69f3-df9e-7d1f-b2c4-91b462f2f4c2"
}
],
"cs-CZ": [
{
"id": "018e69f3-df9e-7d1f-b2c4-91b462f2f4c3",
"locale": "cs-CZ",
"translationKey": "dashboard.title",
"translation": "Přehled",
"translationType": "entities",
"components": ["system"],
"active": true,
"createdAt": "2025-03-16T18:00:00Z",
"updatedAt": "2025-03-16T18:00:00Z",
"deletedAt": null,
"createdBy": "user:012e69f3-df9e-7d1f-b2c4-91b462f2f4c2",
"updatedBy": "user:012e69f3-df9e-7d1f-b2c4-91b462f2f4c2"
}
]
},
"status": 200,
"message": "Translations fetched successfully.",
"requestId": "022e69f3-df9e-7d1f-b2c4-91b462f2f4c2"
}3. Delete Translation by ID
Endpoint: DELETE /translations/{id}
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | UUID | Yes | Translation entry to delete |
Request Logic
sql
UPDATE translations SET "deletedAt" = now(), "updatedBy" = :actor WHERE id = :idSuccess Response (204 No Content)
No body. Translation removed (soft delete).
4. Get Translation Inconsistencies (Missing Keys Across Languages)
Endpoint: GET /translations/inconsistencies
Request Logic
- Identify all unique
translationKeyvalues present in any language. - Cross-check each key against the set of expected locales.
- Return the keys missing in one or more languages, including which ones are missing.
Success Response (200 OK)
json
{
"data": [
{
"translationKey": "dashboard.title",
"missingLocales": ["de-DE", "fr-FR"]
},
{
"translationKey": "invoice.upload.button",
"missingLocales": ["en-GB"]
}
],
"status": 200,
"message": "Translation inconsistencies found.",
"requestId": "uuid-of-request"
}