Skip to content

Machine Translation

View .md

Comvi returns translation suggestions from several providers: one key at a time, as a stream, or as a batch job over many keys.

Machine translation spends the organization’s credits, so it stays with a signed-in person. Every endpoint needs machine_translation.use; the configured-providers read needs machine_translation.view. No scope grants either, so a key built from the six scopes gets 403 FORBIDDEN on every call; only a key created over the API with the raw permission string machine_translation.use passes. Language restrictions apply to the source and the target locale separately.

Common errors: 401 AUTHENTICATION_REQUIRED, 403 FORBIDDEN (missing permission for the source or target locale, or an API key), 403 READ_ONLY_MODE on writes. See Errors.

Provider ID Type Glossary terms in the prompt
Google Translate google Traditional No
DeepL deepl Traditional No
Amazon Translate aws Traditional No
Azure Translator azure Traditional No
OpenAI openai AI Yes
Anthropic Claude anthropic AI Yes

Glossary terms, no-translate terms, translation memory matches, the key description and the project’s AI instructions are assembled into a prompt for the AI providers only. Traditional providers receive the source text and nothing else. Availability depends on the keys the instance administrator has configured.

ICU plural and select messages, including a select wrapping a plural, go through the same suggestions endpoint as plain messages: send the whole message as sourceText. An AI provider translates the whole pattern and rebuilds it with the target language’s plural categories, so an English one/other message can come back with the Ukrainian one/few/many/other set. A traditional provider translates each form on its own and keeps the source’s categories.

GET /v1/projects/{projectId}/mt/configured-providers

Section titled “GET /v1/projects/{projectId}/mt/configured-providers”

Which providers are available on the server. machine_translation.view.

Parameter In Type Required Meaning
projectId path integer Yes Project ID
Terminal window
curl -b cookies.txt https://api.comvi.io/v1/projects/1/mt/configured-providers
{ "providers": { "google": true, "deepl": true, "aws": false, "azure": false, "openai": true, "anthropic": true } }

POST /v1/projects/{projectId}/mt/suggestions

Section titled “POST /v1/projects/{projectId}/mt/suggestions”

Ask each configured provider for a suggestion for one key. Rate limit: 60 requests per minute per caller per project. Suggestions are cached; editing a glossary, the translation memory or the AI instructions does not invalidate the cache, so clear it with DELETE /v1/projects/{projectId}/mt/suggestions.

Parameter In Type Required Meaning
projectId path integer Yes Project ID
key body string Yes Key name, 1 to 512 characters
namespace body string No Default default
sourceLocale body string Yes Source language code
targetLocale body string Yes Target language code. Must differ from sourceLocale
sourceText body string No Text to translate; resolved from the key if omitted
limit body integer No Providers to ask, 1 to 10, default 5. With six providers configured, pass 10 to ask them all
Terminal window
curl -X POST -b cookies.txt -H "Content-Type: application/json" \
-d '{"key": "welcome.message", "sourceLocale": "en", "targetLocale": "uk", "limit": 3}' \
https://api.comvi.io/v1/projects/1/mt/suggestions
[
{ "providerId": "google", "providerLabel": "Google Translate", "text": "Ласкаво просимо до нашого додатку!" },
{ "providerId": "openai", "providerLabel": "OpenAI", "text": "Вітаємо у нашому застосунку!" }
]
Status and code When
400 INVALID_INPUT sourceLocale and targetLocale are the same
403 LIMIT_EXCEEDED The organization has used all its MT credits
422 FIELD_REQUIRED key, sourceLocale or targetLocale is missing
422 VALIDATION_ERROR limit is outside 1 to 10, or a field has the wrong type
429 TOO_MANY_REQUESTS More than 60 requests in a minute

DELETE /v1/projects/{projectId}/mt/suggestions

Section titled “DELETE /v1/projects/{projectId}/mt/suggestions”

Delete the cached suggestions for one key and locale pair, for every provider. Idempotent: an unknown key or an empty cache returns { "deleted": 0 }, not 404. Rate limit: 30 requests per minute per caller per project.

Parameter In Type Required Meaning
projectId path integer Yes Project ID
key body string Yes Key name, 1 to 512 characters
namespace body string No Default default
sourceLocale body string Yes Source language code
targetLocale body string Yes Target language code
Terminal window
curl -X DELETE -b cookies.txt -H "Content-Type: application/json" \
-d '{"key": "welcome.message", "sourceLocale": "en", "targetLocale": "uk"}' \
https://api.comvi.io/v1/projects/1/mt/suggestions
{ "deleted": 3 }
Status and code When
400 INVALID_INPUT sourceLocale and targetLocale are the same
422 FIELD_REQUIRED key, sourceLocale or targetLocale is missing
422 FIELD_TOO_LONG key over 512 characters, or a locale code over 50
422 FIELD_TOO_SHORT key or a locale code is empty
429 TOO_MANY_REQUESTS More than 30 requests in a minute

GET /v1/projects/{projectId}/mt/suggestions/stream

Section titled “GET /v1/projects/{projectId}/mt/suggestions/stream”

The same suggestions as Server-Sent Events, for EventSource. This variant waits for every provider and then writes all suggestion events at once, followed by done. Every 15 seconds the server writes an SSE comment, : ping <milliseconds>, which EventSource ignores. A failure mid-stream arrives as an error event carrying { "message": "..." } and the stream closes; it is not an HTTP status, because the headers were already sent.

Parameter In Type Required Meaning
projectId path integer Yes Project ID
key query string Yes Key name
sourceLocale query string Yes Source language code
targetLocale query string Yes Target language code
namespace query string No Namespace
sourceText query string No Text to translate
limit query integer No 1 to 10, default 5
const url = new URL('https://api.comvi.io/v1/projects/1/mt/suggestions/stream');
url.searchParams.set('key', 'welcome.message');
url.searchParams.set('sourceLocale', 'en');
url.searchParams.set('targetLocale', 'uk');
const source = new EventSource(url, { withCredentials: true });
source.addEventListener('suggestion', (e) => console.log(JSON.parse(e.data).text));
source.addEventListener('error', (e) => { if (e.data) console.error(JSON.parse(e.data).message); source.close(); });
source.addEventListener('done', () => source.close());

POST /v1/projects/{projectId}/mt/suggestions/stream

Section titled “POST /v1/projects/{projectId}/mt/suggestions/stream”

The same suggestions as newline-delimited JSON, delivered as they land. The body is the same as POST /v1/projects/{projectId}/mt/suggestions. Every 15 seconds the server writes a bare newline as a keep-alive, so skip blank lines before parsing.

{"event":"suggestion","data":{"providerId":"google","providerLabel":"Google Translate","text":"Ласкаво просимо!"}}
{"event":"suggestion","data":{"providerId":"deepl","providerLabel":"DeepL","text":"Ласкаво просимо!"}}
{"event":"done","data":{}}

POST /v1/projects/{projectId}/keys/batch/mt

Section titled “POST /v1/projects/{projectId}/keys/batch/mt”

Translate many keys into one or more target locales. One job is queued per target locale, each attempted up to 3 times with exponential backoff starting at 10 seconds.

Parameter In Type Required Meaning
projectId path integer Yes Project ID
keyIds body integer[] Yes At least one
sourceLocaleCode body string Yes Source language code
targetLocaleCodes body string[] Yes At least one. No duplicates, none equal to the source
overwriteExisting body boolean No Default false
Terminal window
curl -X POST -b cookies.txt -H "Content-Type: application/json" \
-d '{"keyIds": [42, 43, 44, 45], "sourceLocaleCode": "en", "targetLocaleCodes": ["uk", "de"]}' \
https://api.comvi.io/v1/projects/1/keys/batch/mt

Returns 202 Accepted. There is no top-level jobId; poll each entry of jobs[]. totalKeys counts the keys sent, not keys times locales.

{
"jobs": [{ "jobId": "1042", "targetLocaleCode": "uk" }, { "jobId": "1043", "targetLocaleCode": "de" }],
"status": "queued", "totalKeys": 4,
"message": "2 batch MT job(s) queued. Subscribe to SSE events for project 1 to receive progress updates."
}
Status and code When
400 INVALID_INPUT targetLocaleCodes has duplicates, or one equals sourceLocaleCode
403 LIMIT_EXCEEDED The organization has used all its MT credits
422 FIELD_REQUIRED keyIds, sourceLocaleCode or targetLocaleCodes is missing
422 VALIDATION_ERROR keyIds or targetLocaleCodes is empty

GET /v1/projects/{projectId}/keys/batch/mt/{jobId}/status

Section titled “GET /v1/projects/{projectId}/keys/batch/mt/{jobId}/status”

Poll one batch job. result is present only when status is completed; a failed job carries error instead.

Parameter In Type Required Meaning
projectId path integer Yes Project ID
jobId path string Yes A jobId from jobs[]
Terminal window
curl -b cookies.txt https://api.comvi.io/v1/projects/1/keys/batch/mt/1042/status
{ "jobId": "1042", "status": "completed", "progress": 100, "result": { "processed": 4, "failed": 0, "duration": 3200.5, "errors": [] } }
status Meaning
waiting In the queue
active Being processed
completed Finished
failed Failed
Status and body When
404 { "error": "Job not found" } Unknown job, or one from another project. Not the standard envelope

POST /v1/projects/{projectId}/keys/batch/mt/{jobId}/cancel

Section titled “POST /v1/projects/{projectId}/keys/batch/mt/{jobId}/cancel”

Cancel a queued job. A job that has started cannot be stopped: the response is 200 with success: false and a message saying it is active, completed or failed. Check success, not the status code.

Terminal window
curl -X POST -b cookies.txt https://api.comvi.io/v1/projects/1/keys/batch/mt/1042/cancel
{ "success": true, "message": "Job cancelled successfully" }
Status and body When
404 { "error": "Job not found" } Unknown job