|
Documentation
Book a DemoPlatform
PlatformMCPCLIAPI
Workflows
GuidesChangelog

Welcome

  • Overview
  • Authentication
  • Errors & status codes
  • Webhook signatures

Localization

  • Overview
  • Create jobs
  • Lock non-translatable keys
  • Track a job group
  • Get a single job
  • List jobs
  • Webhook delivery
  • Live progress (WebSocket)

Pipeline

  • Overview
  • Pre-localization AI edit
  • Human review
  • AI review (post-edit)
  • Rephrase for natural copy
  • Back-translation check
  • Configure the pipeline
  • Observe pipeline runs

Provisioning

  • Overview
  • Create a provisioning job
  • Source types
  • What the AI extracts
  • Webhook delivery
  • Live progress (WebSocket)

Synchronous

  • Localize
  • Recognize

Engine management

  • Engine Suggestions

Track a job group

You created a group, got a groupId back, and now several locales are translating in parallel. You need one question answered, repeatedly, until the work settles: how is the whole submission doing right now? Not locale by locale – the aggregate. How many are done, how many produced output with warnings, how many failed, how many are still running.

That is what this endpoint returns. One poll, every locale's status, in a single response. New to async localization? Start with the Async Localization API overview.

On this page

  • Get a job group
  • Response
  • Group statuses
  • How often to poll
  • When one locale fails

Get a job group#

Retrieve the status of a job group and all its child jobs.

text
GET /jobs/localization/groups/:groupId

Authenticate with your API key in the X-API-Key header, the same key you used to create the group. The groupId is the ljg_-prefixed id from the 202 response.

Response#

The response is a snapshot of the whole submission: the group's own status, four counts, and the child jobs with their individual states. This is the object you read on every poll.

json
{
  "groupId": "ljg_A1b2C3d4E5f6G7h8",
  "status": "processing",
  "sourceLocale": "en",
  "totalJobs": 3,
  "completedJobs": 1,
  "completedWithWarningsJobs": 0,
  "failedJobs": 0,
  "jobs": [
    { "id": "ljb_A1b2C3d4E5f6G7h8", "targetLocale": "de", "status": "completed", "warnings": [], "completedAt": "2026-03-16T10:30:04.000Z" },
    { "id": "ljb_B2c3D4e5F6g7H8i9", "targetLocale": "fr", "status": "processing", "warnings": [], "completedAt": null },
    { "id": "ljb_C3d4E5f6G7h8I9j0", "targetLocale": "ja", "status": "queued", "warnings": [], "completedAt": null }
  ],
  "createdAt": "2026-03-16T10:30:00.000Z"
}

The three count fields for terminal jobs – completedJobs, completedWithWarningsJobs, and failedJobs – sum to the number of locales that have finished. The rest of totalJobs are still queued or processing. In the snapshot above, 1 of 3 is done and 2 are still in flight, so a single read of the counts tells you the work isn't settled yet without scanning the jobs array. When that sum reaches totalJobs, the group has reached a terminal status.

Each job's warnings array surfaces non-critical pipeline stage failures – for example a pre-edit or back-translation step that fell through. A non-empty array means the job still produced output, but at least one optional stage did not complete. The translated outputData itself lives on the single job – fetch that when you're ready to read a finished locale's content.

Group statuses#

The group's status rolls up its child jobs into one value. You poll until it reaches a terminal state.

Group statusMeaning
pendingGroup created, no jobs started yet
processingAt least one job is in progress
completedAll jobs completed successfully
completed_with_warningsAll jobs produced output, but one or more optional pipeline stages failed on at least one job
partialSome jobs completed, some failed
failedAll jobs failed

The split between completed, completed_with_warnings, and partial is the point of this endpoint: it distinguishes "every locale shipped" from "every locale shipped, some with a warning" from "some locales shipped and some didn't" – three outcomes you'd otherwise have to reconstruct by reading each job. partial is not an error; it's a real state of the world that the group reports plainly so your code can branch on it.

How often to poll#

Polling interval

For most jobs, processing takes 2–8 seconds per language. If you're polling instead of using webhooks or WebSocket, a 2-second interval is a reasonable starting point.

Polling is the simplest way to track a group, and for a short-lived batch it's perfectly fine. But it's the weaker option, and worth being honest about: every poll is a round-trip whether or not anything changed, and you learn a locale finished only on your next tick, not the moment it lands.

If you want each result the instant it's ready, don't poll – be told. The platform delivers each completed locale to your webhook URL as it finishes, and a WebSocket connection on the group pushes a full state snapshot on every change, so your UI updates without asking. Reach for polling when a webhook endpoint or a persistent connection is more than the job is worth; reach for push when latency to your UI matters.

When one locale fails#

A skeptical reading of "translate into many locales at once" asks the obvious question first: what happens to the rest when one locale fails? Here is the answer, in the response.

Each locale is an independent job. If German succeeds but Japanese fails, the German translation is finished and delivered normally – the failure does not roll it back. The failed job appears in the group with status: "failed", failedJobs increments, and the group rolls up to partial:

json
{
  "groupId": "ljg_A1b2C3d4E5f6G7h8",
  "status": "partial",
  "sourceLocale": "en",
  "totalJobs": 3,
  "completedJobs": 2,
  "completedWithWarningsJobs": 0,
  "failedJobs": 1,
  "jobs": [
    { "id": "ljb_A1b2C3d4E5f6G7h8", "targetLocale": "de", "status": "completed", "warnings": [], "completedAt": "2026-03-16T10:30:04.000Z" },
    { "id": "ljb_B2c3D4e5F6g7H8i9", "targetLocale": "fr", "status": "completed", "warnings": [], "completedAt": "2026-03-16T10:30:05.000Z" },
    { "id": "ljb_C3d4E5f6G7h8I9j0", "targetLocale": "ja", "status": "failed", "warnings": [], "completedAt": null }
  ],
  "createdAt": "2026-03-16T10:30:00.000Z"
}

Two locales shipped, one didn't, and the counts say so without you scanning anything. To retry, submit a new request with only the failed locales and a fresh idempotency key. The full error description for a failed locale – the errorMessage – lives on the single job; the group gives you the count and the verdict.

Partial failures are a normal state

partial means exactly what the counts show: some locales completed, some failed. The completed locales are already delivered. There's nothing to roll back and no re-spend on the locales that succeeded – you retry only what failed.

Next steps#

Get a single job
Read one locale's translated outputData, warnings, and error message
Webhook delivery
Get each locale's result pushed to you the moment it completes
Live progress (WebSocket)
Stream group snapshots into your UI as each locale lands

Was this page helpful?

Max PrilutskiyMax Prilutskiy·Updated 3 days ago·4 min read