Start bulk background translation of a schema's published documents into target languages.
Queue background translation of all published documents from one or more component schemas into a set of target languages. Results are upserted into the translations table as each translation completes.
Endpoint: POST /translation
Auth: Bearer JWT (WorkOS)
{
"websiteId": "<uuid>",
"schemaNames": ["post", "hero"],
"languages": ["fr", "es", "de"]
}
| Field | Type | Required | Notes |
|---|---|---|---|
websiteId | uuid | yes | Website containing the source documents. |
schemaNames | string[] | yes* | Component schemas to translate. Duplicate names are removed. |
schemaName | string | yes* | Legacy alternative for submitting a single schema. |
languages | string[] | yes | Supported target language codes. Duplicate codes are removed. |
* Provide either schemaNames or schemaName.
Only published documents with non-null published content are considered.
{
"job_id": "<uuid>",
"website_id": "<uuid>",
"schema_name": null,
"schema_names": ["post", "hero"],
"languages": ["fr", "es", "de"],
"status": "queued",
"documents_processed": 12,
"translations_scheduled": 30,
"translations_skipped": 6,
"translations_completed": 0,
"translations_failed": 0,
"reused": false,
"created_at": "2026-07-15T18:00:00Z",
"updated_at": "2026-07-15T18:00:00Z"
}
Returns:
202 Accepted when translations are queued200 OK when every translation is already current| Field | Description |
|---|---|
job_id | Identifier used to retrieve job progress. |
status | Current job status. |
documents_processed | Number of eligible source documents found. |
translations_scheduled | Number of document-language pairs queued. |
translations_skipped | Number skipped because their source hashes are current. |
translations_completed | Number translated successfully. |
translations_failed | Number that failed. |
reused | Whether the response refers to an existing active job. |
Possible job statuses are:
preparingqueuedrunningcompletedcompleted_with_errorsfailedEach document-language pair stores a SHA-256 hash of the source documentβs published content.
A translation is skipped when its stored source hash matches the current published content. This allows the endpoint to be called repeatedly without retranslating unchanged content.
If published content changes while an equivalent job is active, the service rejects the new request. Submit it again after the active job finishes.
Translation runs asynchronously after the initial response.
completed_with_errors.curl -X POST '{TRANSLATION_API_URL}/translation' \
-H 'Authorization: Bearer <workos-jwt>' \
-H 'Content-Type: application/json' \
-d '{
"websiteId": "<uuid>",
"schemaNames": ["post", "hero"],
"languages": ["fr", "es"]
}'
400 Bad Request β schemas or languages are missing, a language is unsupported, or the batch exceeds the configured limit401 Unauthorized β bearer token is missing or invalid409 Conflict β matching work is active, but the published source content changed500 Internal Server Error β source documents could not be prepared or a database operation failedRetrieve the latest progress for a translation job.
Endpoint: GET /translation-jobs/{job_id}
Auth: Bearer JWT (WorkOS)
The response uses the same job object returned by POST /translation, with updated status and progress counts.
{
"job_id": "<uuid>",
"website_id": "<uuid>",
"schema_name": null,
"schema_names": ["post", "hero"],
"languages": ["fr", "es"],
"status": "running",
"documents_processed": 12,
"translations_scheduled": 24,
"translations_skipped": 0,
"translations_completed": 16,
"translations_failed": 1,
"reused": false,
"created_at": "2026-07-15T18:00:00Z",
"updated_at": "2026-07-15T18:01:30Z"
}
curl '{TRANSLATION_API_URL}/translation-jobs/<job-id>' \
-H 'Authorization: Bearer <workos-jwt>'
401 Unauthorized β bearer token is missing or invalid404 Not Found β the job does not exist or is no longer retainedTranslation jobs are currently retained in memory. Job status is lost when the translation service restarts, and multi-instance deployments require sticky routing.