> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tetryx.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Job Lifecycle

> How a job moves through states from submission to terminal result

Every job moves through a defined set of states from creation to completion or failure.

## State machine

```
Pending
  └─▶ Claimed (a runner has taken the job)
        └─▶ Running (simulation executing)
              ├─▶ Completed (success)
              ├─▶ Failed (error, retries exhausted)
              └─▶ Timeout (exceeded timeout_secs)

Pending ──▶ Cancelled
Claimed ──▶ Cancelled
```

`Completed`, `Failed`, `Timeout`, and `Cancelled` are terminal. A terminal job will not be processed again.

## States

### Pending

The job is queued and waiting for a runner to pick it up. Lynx manages distribution — you do not need to assign jobs to runners manually.

### Claimed

A runner has taken ownership of the job and is preparing to execute it. The `assigned_runner` field is set and `claimed_at` is recorded.

### Running

The simulation is actively executing on the runner. The `started_at` timestamp is set.

### Completed

The simulation finished successfully. A `JobResult` is available via `GET /jobs/{job_id}/results`.

### Failed

The simulation failed and all retries are exhausted. The job record includes an `error_message`. A partial `JobResult` may be available with `success: false`.

If `retries < max_retries` at the time of failure, Lynx automatically requeues the job. It returns to `Pending` and gets picked up by the next available runner. The retry counter increments on each attempt.

### Timeout

The job exceeded `timeout_secs` without completing. It is treated as a failed terminal state.

### Cancelled

The job was cancelled before reaching a terminal state.

## Job result

A completed job produces a result accessible via the API:

```json theme={null}
{
  "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "success": true,
  "execution_time_secs": 87,
  "output_files": [
    "s3://your-bucket/runs/3fa85f64/output.csv"
  ],
  "telemetry_data": null,
  "metadata": {
    "run_id": "42",
    "simulation_version": "1.0.0"
  },
  "error_message": null
}
```

Failed jobs have `success: false` and a non-null `error_message`.

## Fetch lifecycle data

```bash theme={null}
# Current job state
curl -s https://api.lynx.tetryx.io/jobs/<job-id> | jq

# Terminal result (available once Completed or Failed)
curl -s https://api.lynx.tetryx.io/jobs/<job-id>/results | jq

# All results for a batch
curl -s https://api.lynx.tetryx.io/batches/<batch-id>/results | jq
```

## Polling for completion

Poll the batch status endpoint until `status` is `Completed` or `Failed`:

```bash theme={null}
curl -s https://api.lynx.tetryx.io/batches/<batch-id> | jq '.batch.status'
```

The `jobs_by_status` field shows the current count in each state, which is useful for progress tracking without fetching every individual job.
