# Lattice Core API Documentation

Base URL: `http://<host>:8000`

Interactive docs (Swagger UI) are available at `/docs` when the server is running.

***

### Authentication

No authentication is required during development. All endpoints accept requests from any origin.

***

### Health Check

#### `GET /healthz`

Lightweight liveness probe.

**Response**

```json
{
  "status": "ok",
  "ray_connected": true
}
```

***

### Jobs

Use the jobs API to submit asynchronous detection work, poll for status, and retrieve results.

#### Submit a Job

**`POST /v1/jobs/submit`**

Submit an asynchronous detection job to the Ray cluster.

**Request Body**

| Field                  | Type      | Required | Description                                                                                    |
| ---------------------- | --------- | -------- | ---------------------------------------------------------------------------------------------- |
| `job_type`             | string    | Yes      | One of `detect_cars`, `detect_vehicles`, or `batch_detect`.                                    |
| `image_paths`          | string\[] | Yes      | One or more image paths on the shared volume. Must contain at least 1 item.                    |
| `model_name`           | string    | No       | YOLO model variant, e.g. `yolov8n.pt`, `yolov8s.pt`, … `yolov8x.pt`. Defaults to `yolov8n.pt`. |
| `confidence_threshold` | float     | No       | Minimum detection confidence between `0.0` and `1.0`. Defaults to `0.5`.                       |
| `vehicle_types`        | string\[] | No       | Vehicle classes to detect (only used with `detect_vehicles`).                                  |
| `priority`             | integer   | No       | Priority from `0`–`10`. Higher = higher priority. Defaults to `0`.                             |
| `callback_url`         | string    | No       | Webhook URL to POST the result to when the job completes.                                      |
| `metadata`             | object    | No       | Arbitrary key-value data passed through to the result.                                         |

**Example Request**

```bash
curl -X POST http://localhost:8000/v1/jobs/submit \
  -H "Content-Type: application/json" \
  -d '{
    "job_type": "detect_cars",
    "image_paths": ["/data/images/frame_001.jpg"],
    "confidence_threshold": 0.6
  }'
```

**Response `202 Accepted`**

```json
{
  "job_id": "a1b2c3d4e5f6",
  "status": "running",
  "message": "Job accepted"
}
```

***

#### Get Job Status

**`GET /v1/jobs/{job_id}/status`**

Poll the current status of a submitted job.

**Path Parameters**

| Parameter | Type   | Description        |
| --------- | ------ | ------------------ |
| `job_id`  | string | The ID of the job. |

**Response `200 OK`**

```json
{
  "job_id": "a1b2c3d4e5f6",
  "status": "running",
  "submitted_at": 1740412800.0,
  "started_at": 1740412800.5,
  "completed_at": null,
  "progress": 0.5,
  "worker_id": "ray_worker_abc123"
}
```

**Status Values**

| Status      | Description                       |
| ----------- | --------------------------------- |
| `pending`   | Queued, not yet started.          |
| `running`   | Currently being processed.        |
| `completed` | Finished successfully.            |
| `failed`    | An error occurred during the job. |

**Errors**

| Code | Description       |
| ---- | ----------------- |
| 404  | Job ID not found. |

***

#### Get Job Result

**`GET /v1/jobs/{job_id}/result`**

Retrieve the result of a completed job.

**Path Parameters**

| Parameter | Type   | Description        |
| --------- | ------ | ------------------ |
| `job_id`  | string | The ID of the job. |

**Response `200 OK`**

```json
{
  "job_id": "a1b2c3d4e5f6",
  "status": "completed",
  "result": {
    "image_path": "/data/images/frame_001.jpg",
    "detections": [
      { "box": [100, 200, 300, 400], "confidence": 0.92, "class": "car" }
    ],
    "car_count": 1,
    "processing_time_ms": 45.2
  },
  "error": null,
  "submitted_at": 1740412800.0,
  "completed_at": 1740412802.3,
  "metadata": null
}
```

**Errors**

| Code | Description                                         |
| ---- | --------------------------------------------------- |
| 404  | Job ID not found.                                   |
| 409  | Job is still pending or running (not yet complete). |

***

### Synchronous Inference

#### `POST /v1/inference/detect`

Run detection on a single image and receive the result directly. This call blocks until inference is complete — best suited for low-latency, single-image requests from edge nodes.

**Request Body**

| Field                  | Type      | Required | Description                                   |
| ---------------------- | --------- | -------- | --------------------------------------------- |
| `image_path`           | string    | Yes      | Image path on the shared volume.              |
| `model_name`           | string    | No       | YOLO model variant. Defaults to `yolov8n.pt`. |
| `confidence_threshold` | float     | No       | Minimum detection confidence (`0.0`–`1.0`).   |
| `vehicle_types`        | string\[] | No       | Vehicle classes to detect.                    |

**Example Request**

```bash
curl -X POST http://localhost:8000/v1/inference/detect \
  -H "Content-Type: application/json" \
  -d '{
    "image_path": "/data/images/frame_001.jpg",
    "confidence_threshold": 0.6
  }'
```

**Response `200 OK`**

```json
{
  "status": "success",
  "image_path": "/data/images/frame_001.jpg",
  "detections": [
    { "box": [100, 200, 300, 400], "confidence": 0.92, "class": "car" }
  ],
  "total_count": 1,
  "processing_time_ms": 45.2,
  "model": "yolov8n.pt",
  "worker_id": "ray_worker_abc123"
}
```

**Errors**

| Code | Description                                |
| ---- | ------------------------------------------ |
| 422  | Detection failed (e.g. invalid image).     |
| 500  | Internal error dispatching to Ray cluster. |

***

### Real-Time Streaming (WebSocket)

#### `WS /v1/stream`

Bidirectional WebSocket for streaming job lifecycle events in real time. Clients receive events for every job state change while connected. Jobs can also be submitted directly over the socket.

**Connecting**

```javascript
const ws = new WebSocket("ws://localhost:8000/v1/stream");
```

**Server → Client Events**

Events are delivered as JSON messages:

```json
{
  "event": "job_completed",
  "job_id": "a1b2c3d4e5f6",
  "status": "completed",
  "timestamp": 1740412802.3
}
```

| Event           | Description                  |
| --------------- | ---------------------------- |
| `job_submitted` | A new job was accepted.      |
| `job_completed` | A job finished successfully. |
| `job_failed`    | A job errored out.           |
| `pong`          | Response to a client `ping`. |
| `error`         | An error occurred.           |

**Client → Server Actions**

Send JSON messages to the server:

**Ping**

```json
{ "action": "ping" }
```

**Submit a job**

```json
{
  "action": "submit",
  "payload": {
    "job_type": "detect_cars",
    "image_paths": ["/data/images/frame_001.jpg"],
    "confidence_threshold": 0.6
  }
}
```

The server responds with a `job_submitted` event containing the new `job_id`.

***

### Cluster Status

#### `GET /v1/cluster/status`

Returns real-time resource information about the Ray GPU cluster.

**Response `200 OK`**

```json
{
  "ray_version": "2.10.0",
  "cluster_alive": true,
  "nodes": [
    {
      "node_id": "abc123",
      "alive": true,
      "resources": { "CPU": 8.0, "GPU": 1.0 }
    }
  ],
  "total_cpus": 8.0,
  "total_gpus": 1.0,
  "available_cpus": 6.0,
  "available_gpus": 0.0,
  "pending_jobs": 0,
  "running_jobs": 1
}
```

**Errors**

| Code | Description              |
| ---- | ------------------------ |
| 503  | Ray cluster unavailable. |

***

### Common Patterns

#### Async Job Workflow

1. **Submit** a job via `POST /v1/jobs/submit` → receive a `job_id`.
2. **Poll** status via `GET /v1/jobs/{job_id}/status` until `status` is `completed` or `failed`.
3. **Fetch** the result via `GET /v1/jobs/{job_id}/result`.

#### Real-Time Workflow

1. **Connect** to `WS /v1/stream`.
2. **Submit** a job via the WebSocket (`action: "submit"`) or REST endpoint.
3. **Listen** for `job_completed` / `job_failed` events on the socket — no polling needed.

#### Choosing Sync vs Async

| Use case                           | Endpoint                    |
| ---------------------------------- | --------------------------- |
| Single image, need result now      | `POST /v1/inference/detect` |
| Batch of images or fire-and-forget | `POST /v1/jobs/submit`      |
| Real-time event feed               | `WS /v1/stream`             |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lattice-1.gitbook.io/lattice-docs/api-reference/readme.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
